Back to Data Structures & Algorithms
2026-02-216 min read

Shell Sort (Data Structures & Algorithms)

Learn Shell Sort (Data Structures & Algorithms) step by step with clear examples and exercises.

Why This Matters

Shell sort is a versatile algorithm used extensively in various fields such as computer science, engineering, and data analysis. Its practical applications range from database management systems to operating systems. Mastering shell sort can help you solve complex problems, debug errors in your code, and prepare for job interviews or exams.

Prerequisites

To follow this lesson, you should be familiar with the following concepts:

  1. Basic Python syntax and control structures (if-else, loops)
  2. Lists and list manipulation in Python
  3. Understanding of big O notation for time complexity analysis
  4. Familiarity with basic sorting algorithms like insertion sort and selection sort
  5. Knowledge of data structures such as arrays and lists
  6. Basic understanding of mathematical operations (e.g., exponentiation, modulus)
  7. Familiarity with Python's built-in math library for mathematical functions
  8. Understanding of the concept of an interval sequence

Core Concept

Shell sort is a modification of the insertion sort algorithm that improves its efficiency for large lists. It works by dividing the input list into smaller sublists called _holes_ based on an _interval sequence_. The algorithm then sorts each sublist using insertion sort, and gradually reduces the interval size until the entire list is sorted.

Interval Sequence

The choice of the interval sequence plays a crucial role in the efficiency of shell sort. A common interval sequence used is the _linear_ or _arithmetic progression_, where the intervals are defined as h[i] = h[0] + i * d, for some starting gap h[0] and increment d. The optimal choice for h[0] and d can significantly affect the sorting time.

Other interval sequences like quadratic, geometric, or cubic progressions can also be used, but their efficiency varies depending on the specific sequence and input data.

Sorting Algorithm

The shell sort algorithm consists of the following steps:

  1. Initialize the interval sequence, usually with h[i] = 2^(i), where i goes from 0 to log2(n).
  2. For each interval in the sequence, perform _gap insertion sort_ on the list. In gap insertion sort, the list is divided into sublists based on the current interval, and each sublist is sorted using insertion sort.
  3. Reduce the interval size by dividing it by a constant factor (usually 2 or 3). Repeat step 2 until the intervals are small enough that insertion sort becomes efficient.
  4. If necessary, perform _linear insertion sort_ on the list to ensure it's fully sorted.

Worked Example

Let's sort the following list using shell sort: [78, 55, 34, 90, 2, 100, 7, 6, 1].

import math

def shell_sort(arr):
n = len(arr)
h = [int(math.floor(n / pow(i, 0.5))) for i in range(1, int(math.floor(log2(n))))]

for gap in h:
for i in range(gap, n):
temp = arr[i]
j = i - gap
while j >= 0 and arr[j] > temp:
arr[j + gap] = arr[j]
j -= gap
arr[j + gap] = temp

if n > 1:
for i in range(n - 1, 0, -1):
if arr[i] < arr[i - 1]:
arr[i], arr[i - 1] = arr[i - 1], arr[i]

return arr

arr = [78, 55, 34, 90, 2, 100, 7, 6, 1]
sorted_arr = shell_sort(arr)
print("Sorted array:", sorted_arr)

Running the above code will sort the list as follows: [2, 6, 7, 34, 55, 78, 90, 100].

Common Mistakes

  1. Incorrect Interval Sequence: Using an inefficient interval sequence can result in slower sorting times. Make sure to use the linear or arithmetic progression as described earlier.
  2. Not Reducing Intervals: If you don't reduce the interval size after each pass, the algorithm will not converge to a sorted list.
  3. Missing Base Case for Linear Insertion Sort: In the worked example, we added an extra step to ensure the list is fully sorted when the intervals are small enough. Make sure to include this step in your code.
  4. Confusing Interval Reduction with Gap Insertion Sort: The interval reduction and gap insertion sort steps are separate. After reducing the intervals, you should perform another pass of gap insertion sort before moving on to smaller intervals.
  5. Incorrect Implementation of Gap Insertion Sort: Make sure your implementation of gap insertion sort is correct, as it's a crucial part of shell sort.
  6. ### Inconsistent Comparison Order
  • Ensure that the comparison order (ascending or descending) remains consistent throughout the algorithm to avoid unexpected results.
  1. ### Ignoring Edge Cases
  • Be aware of edge cases such as empty lists, lists with only one element, and lists containing duplicate elements. Properly handle these cases in your implementation.
  1. ### Overlooking Stability
  • Shell sort is generally unstable, but it can be made stable by maintaining the relative order of equal elements within each sublist before combining them.
  1. ### Inefficient Implementation
  • Optimize your code to minimize unnecessary computations and improve efficiency.
  1. ### Neglecting Time Complexity Analysis
  • Analyze the time complexity of your implementation using big O notation to understand its efficiency in different scenarios.

Practice Questions

Q1: Write a shell sort function in C++ that takes an array as input and sorts it using the linear interval sequence.

#include <iostream>
using namespace std;

void shellSort(int arr[], int n) {
for (int gap = n / 2; gap > 0; gap /= 2) {
for (int i = gap; i < n; i++) {
int temp = arr[i];
int j = i - gap;
while (j >= 0 && arr[j] > temp) {
arr[j + gap] = arr[j];
j -= gap;
}
arr[j + gap] = temp;
}
}
}

int main() {
int arr[] = {78, 55, 34, 90, 2, 100, 7, 6, 1};
int n = sizeof(arr) / sizeof(arr[0]);
shellSort(arr, n);
for (int i = 0; i < n; i++) {
cout << arr[i] << " ";
}
return 0;
}

Q2: Implement a shell sort function in Java that takes an array of integers as input and sorts it using the quadratic interval sequence.

public class ShellSort {
public static void main(String[] args) {
int arr[] = {78, 55, 34, 90, 2, 100, 7, 6, 1};
shellSort(arr);
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
}

public static void shellSort(int arr[]) {
int n = arr.length;
for (int gap = n / 2; gap > 0; gap /= 2) {
for (int i = gap; i < n; i++) {
int temp = arr[i];
int j = i - gap;
while (j >= 0 && arr[j] > temp) {
arr[j + gap] = arr[j];
j -= gap;
}
arr[j + gap] = temp;
}
}
}
}

FAQ

Q: What is the time complexity of shell sort?

A: The time complexity of shell sort, in the average case, is O(n log n). In the worst-case scenario, it can be O(n^2), though this is less common due to the use of an interval sequence.

Q: Can I use different interval sequences for shell sort?

A: Yes, you can experiment with various interval sequences like quadratic, geometric, or cubic progressions. However, the efficiency of these sequences may vary depending on the specific sequence and input data.

Q: Is shell sort a stable sorting algorithm?

A: Shell sort is generally unstable, meaning that it does not maintain the relative order of equal elements. To make it stable, you can modify the algorithm to ensure the relative order of equal elements within each sublist is preserved before combining them.

Q: How does shell sort compare to other sorting algorithms like insertion sort and selection sort?

A: Shell sort is a hybrid sorting algorithm that combines the efficiency of insertion sort for small intervals with the ease of implementation of selection sort. It's generally faster than insertion sort for large lists but slower than quicksort or mergesort in most cases.

Q: Can I implement shell sort in other programming languages?

A: Yes, you can implement shell sort in any programming language that supports basic data structures like arrays and lists. The core concepts and steps remain the same across different languages.

Shell Sort (Data Structures & Algorithms) | Data Structures & Algorithms | XQA Learn