# DSA using Java - Shell Sort

## Overview

Shell sort is a highly efficient sorting algorithm and is based on insertion sort algorithm. This algorithm avoids large shifts as in case of insertion sort if smaller value is very far right and have to move to far left. This algorithm uses insertion sort on widely spread elmements first to sort them and then sorts the less widely spaced elements. This spacing is termed as interval. This interval is calculated based on Knuth's formula as (h=h*3 +1) where h is interval and initial value is 1. This algorithm is quite efficient for medium sized data sets as its average and worst case complexity are of O(n) where n are no. of items.

## Pseudocode

```procedure shellSort( A : array of items )
int innerPosition, outerPosition
int valueToInsert, interval = 1
/* calculate interval*/
while interval < A.length /3 do:
interval = interval * 3 +1

while interval > 0 do:
for outer = interval; outer < A.length; outer ++ do:
/* select value to be inserted */
valueToInsert = A[outer]
inner = outer;
/*shift element towards right*/
while inner > interval -1 && A[inner - interval] >= valueToInsert do:
A[inner] = A[inner-1]
inner = inner - interval
end while
/* insert the number at hole position */
A[inner] = valueToInsert
end for
/* calculate interval*/
interval = (interval -1) /3;
end while
end procedure
```

### Demo Program

```package com.tutorialspoint.advancedsort;

import java.util.Arrays;

public class ShellSortDemo {

public static void main(String[] args){
int[] sourceArray = {4,6,3,2,1,9,7};
System.out.println("Input Array: " +Arrays.toString(sourceArray));
printline(50);
System.out.println("Output Array: "
+ Arrays.toString(shellSort(sourceArray)));
printline(50);
}

public static void printline(int count){
for(int i=0;i <count-1;i++){
System.out.print("=");
}
System.out.println("=");
}

public static int[] shellSort(int[] intArray){
int inner, outer;
int valueToInsert;
int interval = 1;
int elements = intArray.length;
int i=0;
while(interval <= elements/3){
interval = interval*3 +1;
}

while(interval > 0){
System.out.println("iteration "+(i) +"#: "
+Arrays.toString(intArray));
for(outer = interval; outer < elements; outer++){
valueToInsert= intArray[outer];
inner = outer;
while(inner > interval -1 &&
intArray[inner - interval] >= valueToInsert){
intArray[inner] = intArray[inner - interval];
inner -=interval;
System.out.println(" item moved :" + intArray[inner]);
}
intArray[inner] = valueToInsert;
System.out.println(" item inserted :"
+ valueToInsert +", at position :" + inner);
}
interval = (interval -1) /3;
i++;
}
return intArray;
}
}
```

If we compile and run the above program then it would produce following result −

```Input Array: [4, 6, 3, 2, 1, 9, 7]
==================================================
iteration 0#: [4, 6, 3, 2, 1, 9, 7]
item moved :4
item inserted :1, at position :0
item inserted :9, at position :5
item inserted :7, at position :6
iteration 1#: [1, 6, 3, 2, 4, 9, 7]
item inserted :6, at position :1
item moved :6
item inserted :3, at position :1
item moved :6
item moved :3
item inserted :2, at position :1
item moved :6
item inserted :4, at position :3
item inserted :9, at position :5
item moved :9
item inserted :7, at position :5
Output Array: [1, 2, 3, 4, 6, 7, 9]
==================================================
```