Skip to content
Related Articles

Related Articles

Sort a nearly sorted (or K sorted) array

Improve Article
Save Article
  • Difficulty Level : Medium
  • Last Updated : 01 Dec, 2022
Improve Article
Save Article

Given an array of N elements, where each element is at most K away from its target position, devise an algorithm that sorts in O(N log K) time.

Examples: 

Input: arr[] = {6, 5, 3, 2, 8, 10, 9}, K = 3 
Output: arr[] = {2, 3, 5, 6, 8, 9, 10}

Input: arr[] = {10, 9, 8, 7, 4, 70, 60, 50}, k = 4
Output: arr[] = {4, 7, 8, 9, 10, 50, 60, 70}

Recommended Practice

Sort a nearly sorted (or K sorted) array using insertion sort:

To solve the problem follow the below idea:

We can use insertion sort to sort the array efficiently as index of every element can be changed by atmost K places, which will reduce the time complexity of this algorithm from O(N2) to O(NK).

Follow the below steps to solve the problem:

  • Iterate from arr[1] to arr[N] over the array. 
  • Compare the current element (key) to its predecessor. 
  • If the key element is smaller than its predecessor, compare it to the elements before. Move the greater elements one position up to make space for the swapped element.

Below is the implementation of the above approach: 

C++




/* C++ Function to sort an array using insertion sort*/
 
#include <bits/stdc++.h>
using namespace std;
 
void insertionSort(int A[], int size)
{
    int i, key, j;
    for (i = 1; i < size; i++) {
        key = A[i];
        j = i - 1;
 
        /* Move elements of A[0..i-1], that are
           greater than key, to one
           position ahead of their current position.
           This loop will run at most k times */
        while (j >= 0 && A[j] > key) {
            A[j + 1] = A[j];
            j = j - 1;
        }
        A[j + 1] = key;
    }
   
  for(int i=0; i<size; i++)
      cout<<A[i]<<" ";
   
  cout<<endl;
}
 
int main()
{
      int A[] = {6, 5, 3, 2, 8, 10, 9};
      int size = 7;
      insertionSort(A, size);   
   
    return 0;
}
 
// This code is contributed by Shivani


C




/* Function to sort an array using insertion sort*/
void insertionSort(int A[], int size)
{
    int i, key, j;
    for (i = 1; i < size; i++) {
        key = A[i];
        j = i - 1;
 
        /* Move elements of A[0..i-1], that are
           greater than key, to one
           position ahead of their current position.
           This loop will run at most k times */
        while (j >= 0 && A[j] > key) {
            A[j + 1] = A[j];
            j = j - 1;
        }
        A[j + 1] = key;
    }
}


Java




/* Function to sort an array using insertion sort*/
static void insertionSort(int A[], int size)
{
    int i, key, j;
    for (i = 1; i < size; i++) {
        key = A[i];
        j = i - 1;
 
        /* Move elements of A[0..i-1], that
            are greater than key, to one
            position ahead of their current position.
            This loop will run at most k times */
        while (j >= 0 && A[j] > key) {
            A[j + 1] = A[j];
            j = j - 1;
        }
        A[j + 1] = key;
    }
}


Python3




# Function to sort an array using
# insertion sort
 
 
def insertionSort(A, size):
    i, key, j = 0, 0, 0
    for i in range(size):
        key = A[i]
        j = i-1
 
        # Move elements of A[0..i-1], that are
        # greater than key, to one position
        # ahead of their current position.
        # This loop will run at most k times
        while j >= 0 and A[j] > key:
            A[j + 1] = A[j]
            j = j - 1
        A[j + 1] = key


C#




/* C# Function to sort an array using insertion sort*/
static void insertionSort(int A[], int size)
{
    int i, key, j;
 
    for (i = 1; i < size; i++) {
        key = A[i];
        j = i - 1;
 
        /* Move elements of A[0..i-1], that are greater than
           key, to one position ahead of their current
           position. This loop will run at most k times */
        while (j >= 0 && A[j] > key) {
            A[j + 1] = A[j];
            j = j - 1;
        }
        A[j + 1] = key;
    }
}


Javascript




/* Function to sort an array using insertion sort*/
function insertionSort(A, size)
{
   var i, key, j;
   for (i = 1; i < size; i++)
   {
       key = A[i];
       j = i-1;
 
       /* Move elements of A[0..i-1], that are
          greater than key, to one
          position ahead of their current position.
          This loop will run at most k times */
       while (j >= 0 && A[j] > key)
       {
           A[j+1] = A[j];
           j = j-1;
       }
       A[j+1] = key;
   }
}
 
// This code is contributed by itsok.


Output

2 3 5 6 8 9 10 

Time Complexity: O(N*K), The inner loop will run at most K times. To move every element to its correct place, at most K elements need to be moved. 
Auxiliary Space: O(1)

Complete Interview Preparation - GFG

Sort a nearly sorted (or K sorted) array using heap:

Follow the below steps to solve the problem:

  • Create a Min Heap of size K+1 with the first K+1 elements. We are creating a heap of size K as the element can be at most K distance from its index in a sorted array. 
  • One by one remove the min element from the heap, put it in the result array, and add a new element to the heap from the remaining elements.

Below is the implementation of the above approach:

C++




// A STL based C++ program to sort a nearly sorted array.
#include <bits/stdc++.h>
using namespace std;
 
// Given an array of size n, where every element
// is k away from its target position, sorts the
// array in O(n logk) time.
void sortK(int arr[], int n, int k)
{
 
    // Insert first k+1 items in a priority queue (or min
    // heap)
    //(A O(k) operation). We assume, k < n.
    // if size of array = k i.e k away from its target
    // position then
    int size;
    size = (n == k) ? k : k + 1;
    priority_queue<int, vector<int>, greater<int> > pq(
        arr, arr + size);
 
    // i is index for remaining elements in arr[] and index
    // is target index of for current minimum element in
    // Min Heap 'pq'.
    int index = 0;
    for (int i = k + 1; i < n; i++) {
        arr[index++] = pq.top();
        pq.pop();
        pq.push(arr[i]);
    }
 
    while (pq.empty() == false) {
        arr[index++] = pq.top();
        pq.pop();
    }
}
 
// A utility function to print array elements
void printArray(int arr[], int size)
{
    for (int i = 0; i < size; i++)
        cout << arr[i] << " ";
    cout << endl;
}
 
// Driver code
int main()
{
    int k = 3;
    int arr[] = { 2, 6, 3, 12, 56, 8 };
    int n = sizeof(arr) / sizeof(arr[0]);
   
      // Function call
    sortK(arr, n, k);
 
    printArray(arr, n);
 
    return 0;
}


Java




// Java program to sort a nearly sorted array
import java.util.Iterator;
import java.util.PriorityQueue;
 
class GFG {
    private static void kSort(int[] arr, int n, int k)
    {
        if (arr == null || arr.length == 0) {
            return;
        }
        // min heap
        PriorityQueue<Integer> priorityQueue
            = new PriorityQueue<>();
        // if there are less than k + 1 elements present in
        // the array
        int minCount = Math.min(arr.length, k + 1);
        // add first k + 1 items to the min heap
        for (int i = 0; i < minCount; i++) {
            priorityQueue.add(arr[i]);
        }
 
        int index = 0;
        for (int i = k + 1; i < n; i++) {
            arr[index++] = priorityQueue.peek();
            priorityQueue.poll();
            priorityQueue.add(arr[i]);
        }
 
        Iterator<Integer> itr = priorityQueue.iterator();
 
        while (itr.hasNext()) {
            arr[index++] = priorityQueue.peek();
            priorityQueue.poll();
        }
    }
 
    // A utility function to print the array
    private static void printArray(int[] arr, int n)
    {
        for (int i = 0; i < n; i++)
            System.out.print(arr[i] + " ");
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        int k = 3;
        int arr[] = { 2, 6, 3, 12, 56, 8 };
        int n = arr.length;
       
          // function call
        kSort(arr, n, k);
        printArray(arr, n);
    }
}
 
// This code is contributed by
// Manpreet Singh(manpreetsngh294)


Python3




# A Python3 program to sort a
# nearly sorted array.
 
from heapq import heappop, heappush, heapify
 
 
# A utility function to print
# array elements
def print_array(arr: list):
    for elem in arr:
        print(elem, end=' ')
 
# Given an array of size n, where every
# element is k away from its target
# position, sorts the array in O(nLogk) time.
 
 
def sort_k(arr: list, n: int, k: int):
    """
    :param arr: input array
    :param n: length of the array
    :param k: max distance, which every
     element is away from its target position.
    :return: None
    """
    # List of first k+1 items
    heap = arr[:k + 1]
 
    # using heapify to convert list
    # into heap(or min heap)
    heapify(heap)
 
    # "rem_elmnts_index" is index for remaining
    # elements in arr and "target_index" is
    # target index of for current minimum element
    # in Min Heap "heap".
    target_index = 0
    for rem_elmnts_index in range(k + 1, n):
        arr[target_index] = heappop(heap)
        heappush(heap, arr[rem_elmnts_index])
        target_index += 1
 
    while heap:
        arr[target_index] = heappop(heap)
        target_index += 1
 
 
# Driver Code
k = 3
arr = [2, 6, 3, 12, 56, 8]
n = len(arr)
sort_k(arr, n, k)
 
print_array(arr)
 
# This code is contributed by
# Veerat Beri(viratberi)


C#




// A C# program to sort a nearly sorted array
using System;
using System.Collections.Generic;
class GFG {
 
    static void kSort(int[] arr, int n, int k)
    {
 
        // min heap
        List<int> priorityQueue = new List<int>();
 
        // add first k + 1 items to the min heap
        for (int i = 0; i < k + 1; i++) {
            priorityQueue.Add(arr[i]);
        }
 
        priorityQueue.Sort();
 
        int index = 0;
        for (int i = k + 1; i < n; i++) {
            arr[index++] = priorityQueue[0];
            priorityQueue.RemoveAt(0);
            priorityQueue.Add(arr[i]);
            priorityQueue.Sort();
        }
 
        int queue_size = priorityQueue.Count;
 
        for (int i = 0; i < queue_size; i++) {
            arr[index++] = priorityQueue[0];
            priorityQueue.RemoveAt(0);
        }
    }
 
    // A utility function to print the array
    static void printArray(int[] arr, int n)
    {
        for (int i = 0; i < n; i++)
            Console.Write(arr[i] + " ");
    }
 
    // Driver code
    static void Main()
    {
        int k = 3;
        int[] arr = { 2, 6, 3, 12, 56, 8 };
        int n = arr.Length;
        kSort(arr, n, k);
        printArray(arr, n);
    }
}
 
// This code is contributed by divyeshrabadiya07.


Javascript




<script>
// A javascript program to sort a nearly sorted array
 
function kSort(arr,n,k)
{
    let priorityQueue=[];
    // add first k + 1 items to the min heap
        for (let i = 0; i < k + 1; i++) {
            priorityQueue.push(arr[i]);
        }
        priorityQueue.sort(function(a,b){return a-b;});
  
        let index = 0;
        for (let i = k + 1; i < n; i++) {
            arr[index++] = priorityQueue[0];
            priorityQueue.shift();
            priorityQueue.push(arr[i]);
            priorityQueue.sort(function(a,b){return a-b;});
        }
  
         
  
        while (priorityQueue.length != 0) {
            arr[index++] = priorityQueue[0];
            priorityQueue.shift();
        }
}
 
// A utility function to print the array
function printArray(arr,n)
{
    for (let i = 0; i < n; i++)
            document.write(arr[i] + " ");
}
 
// Driver Code
let k = 3;
let arr = [ 2, 6, 3, 12, 56, 8 ];
let n = arr.length;
kSort(arr, n, k);
 
printArray(arr, n);
 
// This code is contributed by unknown2108
</script>


Output

Following is sorted array
2 3 6 8 12 56 

Time Complexity: O(K) + O(m * log(k)) ,  where M = N – K
Auxiliary Space: O(K)

Note: We can also use a Balanced Binary Search Tree instead of a Heap to store k+1 elements. The insert and delete operations on Balanced BST also take O(log k) time. So Balanced BST-based method will also take O(n log k) time, but the Heap based method seems to be more efficient as the minimum element will always be at the root. Also, Heap doesn’t need extra space for left and right pointers.

Sort a nearly sorted (or K sorted) array using Quick-Sort:

To solve the problem follow the below idea:

The algorithm uses quick sort but changes the partition function in 2 ways.

  1. Selects the pivot element as the middle element instead of the first or last element.
  2. Scans the array from max(low, mid – k) to min(mid + k, high) instead of low to high.

The middle element is chosen as the pivot for diving the array into almost 2 halves for logarithmic time complexity

Below is the implementation of the above approach:

C++




// C++ program for the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
int sort(vector<int>& array, int l, int h, int k)
{
    int mid
        = l + (h - l) / 2; // Choose middle element as pivot
    int i = max(l, mid - k), j = i,
        end = min(mid + k, h); // Set appropriate range
    swap(array[mid],
         array[end]); // Swap middle and last element to
                      // avoid extra complications
    while (j < end) {
        if (array[j] < array[end]) {
            swap(array[i++], array[j]);
        }
        j = j + 1;
    }
    swap(array[end], array[i]);
    return i;
}
 
void ksorter(vector<int>& array, int l, int h, int k)
{
    if (l < h) {
        int q = sort(array, l, h, k);
        ksorter(array, l, q - 1, k);
        ksorter(array, q + 1, h, k);
    }
}
 
// Driver code
int main()
{
    vector<int> array(
        { 3, 3, 2, 1, 6, 4, 4, 5, 9, 7, 8, 11, 12 });
    int k = 3;
    cout << "Array before K sort\n";
    for (int& num : array)
        cout << num << ' ';
    cout << endl;
   
      // Function call
    ksorter(array, 0, array.size() - 1, k);
    cout << "Array after K sort\n";
    for (int& num : array)
        cout << num << ' ';
    return 0;
}


Java




// Java program for above approach
import java.io.*;
import java.util.*;
 
class GFG {
    public static int sort(ArrayList<Integer> arr, int l,
                           int h, int k)
    {
        int mid
            = l
              + (h - l)
                    / 2; // choose middle element as pivot
        int i = Math.max(l, mid - k), j = i,
            end = Math.min(mid + k,
                           h); // set appropriate ranges
        Collections.swap(
            arr, end, mid); // swap middle and last element
                            // to avoid extra complications
        while (j < end) {
            if (arr.get(j) < arr.get(end)) {
                Collections.swap(arr, j, i++);
            }
            j = j + 1;
        }
        Collections.swap(arr, end, i);
        return i;
    }
 
    public static void ksorter(ArrayList<Integer> arr,
                               int l, int h, int k)
    {
        if (l < h) {
            int q = sort(arr, l, h, k);
            ksorter(arr, l, q - 1, k);
            ksorter(arr, q + 1, h, k);
        }
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        ArrayList<Integer> arr = new ArrayList<>(List.of(
            3, 3, 2, 1, 6, 4, 4, 5, 9, 7, 8, 11, 12));
        int k = 3;
        int N = arr.size();
 
        System.out.println("Array before K sort\n");
        System.out.println(arr);
        System.out.println("\n");
 
        ksorter(arr, 0, N - 1, k);
 
        System.out.println("Array after K sort\n");
        System.out.println(arr);
    }
}
// this code is contributed by aditya942003patil


C#




// C# program for above approach
using System;
 
public class GFG {
    public static void
    swap(int[] array, int i,
         int j) // function to swap two numbers
    {
        int temp = array[i];
        array[i] = array[j];
        array[j] = temp;
    }
    public static int sort(int[] array, int l, int h, int k)
    {
        int mid
            = l
              + (h - l)
                    / 2; // choose middle element as pivot
        int i = Math.Max(l, mid - k), j = i,
            end = Math.Min(mid + k,
                           h); // set appropriate ranges
        swap(array, end,
             mid); // swap middle and last element to avoid
                   // extra complications
        while (j < end) {
            if (array[j] < array[end]) {
                swap(array, j, i++);
            }
            j = j + 1;
        }
        swap(array, end, i);
        return i;
    }
 
    public static void ksorter(int[] array, int l, int h,
                               int k)
    {
        if (l < h) {
            int q = sort(array, l, h, k);
            ksorter(array, l, q - 1, k);
            ksorter(array, q + 1, h, k);
        }
    }
 
    // Driver Code
    public static void Main()
    {
        int[] array
            = { 3, 3, 2, 1, 6, 4, 4, 5, 9, 7, 8, 11, 12 };
        int k = 3;
        int N = array.Length;
 
        Console.WriteLine("Array before K sort\n");
        for (int i = 0; i < N; i++)
            Console.Write(array[i] + " ");
        Console.WriteLine("\n");
 
        ksorter(array, 0, N - 1, k);
 
        Console.WriteLine("Array after K sort\n");
        for (int i = 0; i < N; i++)
            Console.Write(array[i] + " ");
        Console.WriteLine("\n");
    }
}
// this code is contributed by Abhijeet Kumar(abhijeet19403)


Output

Array before k sort
3 3 2 1 6 4 4 5 9 7 8 11 12 
Array after k sort
1 2 3 3 4 4 5 6 7 8 9 11 12 

Time Complexity: O(N * Log N) 
Auxiliary Space: O(Log N)

Please write comments if you find any of the above codes/algorithms incorrect, or find other ways to solve the same problem. 


My Personal Notes arrow_drop_up
Related Articles

Start Your Coding Journey Now!