Shell Sort

Last Updated : 20 Dec, 2025

Shell Sort, also known as Shell's method, is an in-place comparison sort and an optimization of Insertion Sort. It improves upon the efficiency of Insertion Sort by allowing elements to be moved over larger distances in the initial stages, which significantly reduces the number of swaps required, especially for larger datasets. 

  • It was considered as the first algorithm to break the O(n²) time complexity barrier for sorting.
  • It works by comparing elements that are far apart first, then gradually reducing the gap. This allows faster movement of elements across the array.

Steps used in the algorithm are,

  1. Choose a gap sequence (commonly n/2, n/4, ... , 1).
  2. Sort elements at each gap using Insertion Sort.
  3. Reduce the gap and repeat until the gap becomes 1.

Let's sort the list [22, 34, 25, 12, 64, 11, 90, 88, 45] using Shell Sort :


C++
#include <iostream>
#include <vector>
using namespace std;
 
void shellSort(vector<int>& arr) {
    int n = arr.size();

    // Start with a large gap, then reduce it step by step
    for (int gap = n / 2; gap > 0; gap /= 2) {

        // Perform a "gapped" insertion sort for this gap size
        for (int i = gap; i < n; i++) {
            
            // Current element to be placed correctly
            int temp = arr[i];  
            int j = i;

            // Shift elements that are greater than temp to make space
            while (j >= gap && arr[j - gap] > temp) {
                arr[j] = arr[j - gap];
                j -= gap;
            }

            // Place temp in its correct location
            arr[j] = temp;
        }
    }
}

// Utility function to print the vector
void printArray(const vector<int>& arr) {
    for (int num : arr)
        cout << num << " ";
    cout << endl;
}

int main() {
    vector<int> arr = {12, 34, 54, 2, 3}; 

    shellSort(arr);
    printArray(arr);

    return 0;
}
Java
public class GFG {
 
    public static void shellSort(int[] arr) {
        int n = arr.length;

        // Start with a large gap, then reduce it step by step
        for (int gap = n / 2; gap > 0; gap /= 2) {

            // Perform a "gapped" insertion sort for this gap size
            for (int i = gap; i < n; i++) {
                
                // Current element to be placed correctly
                int temp = arr[i]; 
                int j = i;

                // Shift earlier elements that are greater than temp
                while (j >= gap && arr[j - gap] > temp) {
                    arr[j] = arr[j - gap];
                    j -= gap;
                }

                // Place temp in its correct position
                arr[j] = temp;
            }
        }
    }

    // Utility function to print array
    public static void printArray(int[] arr) {
        for (int num : arr) {
            System.out.print(num + " ");
        }
        System.out.println();
    }
 
    public static void main(String[] args) {
        int[] arr = {12, 34, 54, 2, 3};
        
        shellSort(arr);
        printArray(arr);
    }
}
Python
def shell_sort(arr):
    n = len(arr)

    gap = n // 2
    while gap > 0:

        # Perform a "gapped" insertion sort for this gap size
        for i in range(gap, n):
            
            # Current element to be placed correctly
            temp = arr[i]   
            j = i

            # Shift earlier elements that are greater than temp
            while j >= gap and arr[j - gap] > temp:
                arr[j] = arr[j - gap]
                j -= gap

            # Place temp in its correct position
            arr[j] = temp

        # Reduce the gap
        gap //= 2


# Utility function to print array
def print_array(arr):
    print(" ".join(map(str, arr)))

 
if __name__ == "__main__":
    arr = [12, 34, 54, 2, 3] 

    shell_sort(arr)
    print_array(arr)
C#
using System;

class GFG
{ 
    public static void ShellSort(int[] arr)
    {
        int n = arr.Length;

        // Start with a large gap, then reduce it step by step
        for (int gap = n / 2; gap > 0; gap /= 2)
        {
            // Perform a "gapped" insertion sort for this gap size
            for (int i = gap; i < n; i++)
            {   
                // Current element to be placed correctly
                int temp = arr[i]; 
                int j = i;

                // Shift earlier elements that are greater than temp
                while (j >= gap && arr[j - gap] > temp)
                {
                    arr[j] = arr[j - gap];
                    j -= gap;
                }

                // Place temp in its correct position
                arr[j] = temp;
            }
        }
    }

    // Utility function to print array
    public static void PrintArray(int[] arr)
    {
        foreach (int num in arr)
        {
            Console.Write(num + " ");
        }
        Console.WriteLine();
    }

    public static void Main()
    {
        int[] arr = { 12, 34, 54, 2, 3 };

        ShellSort(arr);
        PrintArray(arr);
    }
}
JavaScript
function shellSort(arr) {
    let n = arr.length;

    // Start with a large gap, then reduce it step by step
    for (let gap = Math.floor(n / 2); gap > 0; gap = Math.floor(gap / 2)) {

        // Perform a "gapped" insertion sort for this gap size
        for (let i = gap; i < n; i++) {
            
            // Current element to be placed correctly
            let temp = arr[i]; 
            let j = i;

            // Shift earlier elements that are greater than temp
            while (j >= gap && arr[j - gap] > temp) {
                arr[j] = arr[j - gap];
                j -= gap;
            }

            // Place temp in its correct position
            arr[j] = temp;
        }
    }
}

// Utility function to print array
function printArray(arr) {
    console.log(arr.join(" "));
}

// Driver code
let arr = [12, 34, 54, 2, 3]; 

shellSort(arr);
printArray(arr);

Output
2 3 12 34 54 

Complexity Analysis of Shell Sort:

Time Complexity:

  • Best Case: O(n log n), when the array is already nearly sorted (depends on gap sequence).
  • Average Case: Between O(n^1.25) and O(n^1.5), depending on the chosen gap sequence.
  • Worst Case: O(n²), with simple gap sequences like n/2, n/4, …, 1.

Auxiliary Space: O(1), as it sorts in-place.
Stability: Not stable (equal elements may not retain their original relative order).

Applications of Shell Sort:

  • Suitable for medium-sized arrays where O(n log n) algorithms (like Merge Sort) are too heavy.
  • Useful in embedded systems where memory is limited (due to in-place sorting).
  • Sometimes used as a subroutine in hybrid algorithms.

Advantages

  • In-place Sorting: Requires only O(1) extra space.
  • Faster than Insertion Sort: Especially for larger arrays.
  • Easy to Implement: Straightforward improvement over Insertion Sort.

Disadvantages

  • Not Stable: Does not maintain the order of equal elements.
  • Performance depends on gap sequence: Bad choices can lead to O(n²).
  • Slower than advanced algorithms: Merge Sort, Quick Sort, and Tim Sort usually outperform it on large datasets.
Comment