The eight-year-old daughter of Heap Sort and Cocktail Shaker Sort, she absolutely *loves* to tell you all about her day: what things she ate, this cool car she saw on the way over, how

The indefatigable Bubble Sort is beloved by her whole family, provided she isn't in the room.

The eight-year-old daughter of Heap Sort and Cocktail Shaker Sort, she absolutely *loves* to tell you all about her day: what things she ate, this cool car she saw on the way over, how her little brother is annoying her at that particular moment, what she wants for her birthday in eight months. Everything.

Her parents adore her, but sometimes the family wishes she would just shut up for five minutes. All except for grandma Merge Sort, who could listen to little Bubbly's stories and exclamations for days. No wonder she loves going to Grandma's house.

**Created By:**Unknown (Popularized by Donald Knuth)**Type:**Exchange**Stable?**Yes**Best-Case:***O(n*^{2})**Average-Case:***O(n*^{2})**Worst-Case:***O(n*^{2})**Space Complexity:***O(n)***Sample Project:**Over on GitHub

- FOR each item in the collection
- IF two adjoining elements are in the wrong order, SWAP them.
- GO TO 1, CONTINUE until the list is sorted.

This animation is a good example of Bubble Sort, because like Bubble Sort it takes FOREVER to get anything done. So let's try another example.

Say we have the following collection:

{ 5, 8, 2, 4, 1 }

Bubble sort will swap elements on each pass that are not in the correct order. Here's the position of the collection elements after each swap:

{ 5, 2, 8, 4, 1 }

{ 5, 2, 4, 8, 1 }

{ 5, 2, 4, 1, 8 }

{ 2, 5, 4, 1, 8 }

{ 2, 4, 5, 1, 8 }

{ 2, 4, 1, 5, 8 }

{ 2, 1, 4, 5, 8 }

{ 1, 2, 4, 5, 8 }

In order to do this sort, the algorithm has to complete 4 passes of the array in order to sort 5 elements. That's wildly inefficient.

...But cool to watch. Check out this "audibilization" from YouTube:

```
class BubbleSort
{
public static void Main(string[] args)
{
int[] array = { 92, 28, 3, 71, 50, 14, 24, 20, 66, 70, 45, 17, 9, 99, 38 };
int temp;
Console.WriteLine("Bubble Sort");
CommonFunctions.PrintInitial(array);
//1. For each item in the array...
for (int i = 0; i <= array.Length - 2; i++)
{
for (int j = 0; j <= array.Length - 2; j++)
{
//2. ...if two adjoining elements are in the wrong order, swap them.
if (array[j] > array[j + 1])
{
temp = array[j + 1];
array[j + 1] = array[j];
array[j] = temp;
}
//3. Repeat this for all pairs of elements.
}
}
CommonFunctions.PrintFinal(array);
Console.ReadLine();
}
}
```

Bubble Sort is, to put it frankly, the worst sorting algorithm that isn't trying to be bad. The *best-*case scenario is still O(n^{2}). It is inefficient, slow, and generally a poor-performing sort, despite how easy the algorithm is to implement. That simplicity is really this algorithm's only redeeming value: it's easy to teach, in a "this is what you should not do" sort of way.

In short, Bubble Sort should not be used for real-world sorting scenarios.

Bubble Sort is a highly inefficient sorting algorithm that traverses through a collection, swapping neighboring values if they are out of order. It has an implementation only a mother could love. Or, perhaps, a grandmother?

Don't forget to check out the sample project over on GitHub!

Happy Coding!

]]>The two-year-old son of Heap Sort and Cocktail Shaker Sort, he is possibly the most mischievous scamp this side of the Mississippi, or at least that's what his grandfather would say.

A favorite trick of

]]>Bogosort is adorable, when he isn't running away.

The two-year-old son of Heap Sort and Cocktail Shaker Sort, he is possibly the most mischievous scamp this side of the Mississippi, or at least that's what his grandfather would say.

A favorite trick of his happens when the family plays poker, or Uno, or any other game involving cards. He sneaks up to the table (he can be very quite when he wants to be) and runs off with as many cards as his little hands can grab. As you might imagine, this dramatically improves the game, at least in his tiny opinion. The adults who have to spend time chasing him down, vaulting over dogs and rounding corners at dangerously high speeds, might disagree.

**Created By:**Unknown**Type:**Exchange**Stable?**Yes**Best-Case:***O(n)***Average-Case:***O((n + 1)!)***Worst-Case:**Unbounded**Space Complexity:***O(1)***Sample Project:**Over on GitHub

- IF the list is not sorted...
- SHUFFLE the list randomly
- GO TO 1, CONTINUE until list is sorted.

A visualization for this particular sorting algorithm is kind of ridiculous. The procedure is just "shuffle randomly until sorted", very much like taking a deck of cards, throwing them into the air, gathering them up, and repeating this until the deck is in the correct order.

If you think this algorithm is amazingly stupid, you are not wrong.

But it's not the slowest algorithm ever. That honor goes to Bogobogosort, an algorithm that was specifically designed to be as slow as possible while still doing a ton of work. The author's own guess on that algorithm's time complexity is *O(n! ^{n!}). *That's just crazy.

That said, the "audibilization" of Bogosort is pretty neat: a ton of noise for not very much gain:

```
class BogoSort
{
static void Main(string[] args)
{
List<int> list = new List<int>() { 2, 1, 3, 0 };
Console.WriteLine("BogoSort");
Console.WriteLine("Sorting...");
Sort(list);
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
static void Sort(List<int> list)
{
int iteration = 0;
while (!IsSorted(list))
{
PrintIteration(list, iteration);
list = Shuffle(list); //Shuffle the numbers randomly
iteration++;
}
PrintIteration(list, iteration); //Print the final, sorted iteration
Console.WriteLine();
Console.WriteLine("BogoSort completed after {0} iterations.", iteration);
}
static void PrintIteration(List<int> list, int iteration)
{
Console.Write("BogoSort iteration #{0}: ", iteration);
foreach(var value in list)
{
Console.Write($"{value} ");
}
Console.WriteLine();
}
static bool IsSorted(List<int> list)
{
for (int i = 0; i < list.Count - 1; i++)
{
if (list[i] > list[i + 1])
{
return false;
}
}
return true;
}
//Shuffle algorithm based on Fisher-Yates method.
static List<int> Shuffle(List<int> numbers)
{
Random r = new Random();
//Step 1: For each unshuffled item in the collection
for (int n = numbers.Count - 1; n > 0; --n)
{
//Step 2: Randomly pick an item which has not been shuffled
int k = r.Next(n + 1);
//Step 3: Swap the selected item with the last "unstruck" item in the collection
int temp = numbers[n];
numbers[n] = numbers[k];
numbers[k] = temp;
}
return numbers;
}
}
```

Any time you see a factorial (!) in a math equation, and you want that number to be small, you're gonna have a bad time. The average-case for Bogosort is *O((n + 1)!). *This means that, as the size of the collection increases, the time the algorithm requires to shuffle the collection increases *dramatically*. There's a reason why the implementation above has only four numbers in the starting collection; any more and I was getting hundreds of permutations before finding a solution (if one was found at all).

Obviously, Bogosort isn't meant to be taken seriously as a sorting algorithm. It's not useful in the real world; the algorithm can be reduced to "shuffle until sorted" which might take forever. That said, it can be useful, in a "do not do this" kind of way. Just make sure he can't reach the cards.

Don't forget to check out the sample project over on GitHub!

Happy Coding!

]]>The father of four rambunctious children and husband to the always-working Heap Sort, "Shaky" (a loving nickname for him which is never said to his face) is a stay-at-home dad who absolutely adores his children but just

]]>Cocktail Shaker Sort would like a drink. A strong one, if you please.

The father of four rambunctious children and husband to the always-working Heap Sort, "Shaky" (a loving nickname for him which is never said to his face) is a stay-at-home dad who absolutely adores his children but just wants some alone time, is that so much to ask?

The problem is that, when he gets his alone time (rare as it is), he would greatly prefer to curl up with his beloved Heapy, but failing that, he'll make a stiff drink that the rest of the family can't be in the same room as. Not that he minds. Heapy is his best friend, his companion, his true love, but the rest of her family he could take or leave. Nevertheless, his kids love him, and the family has accepted him, even if he hasn't quite gotten around to feeling the same way.

**Created By:**Donald Knuth (1973)**AKA:**Bidirectional Bubble Sort**Type:**Exchange**Stable?**Yes**Best-Case:***O(n log n)***Average-Case:***O(n log n)***Worst-Case:***O(n log n)***Space Complexity:***O(n)***Sample Project:**Over on GitHub

- PASS THROUGH the collection from left-to-right.
- DURING that pass, SELECT the highest encountered value.
- DEPOSIT that value at the end of the considered range.
- DECREASE the end of the considered range by 1.
- PASS THROUGH the collection from right-to-left.
- DURING that pass, SELECT the lowest encountered value.
- DEPOSIT that value at the beginning of the considered range.
- INCREASE the start of the considered range by 1.
- GO TO 1, CONTINUE until the range is 0.

Lucky for us, Cocktail Shaker sort is an easy sort to understand. On each pass through the collection, it either finds the highest or lowest encountered value (depending on pass direction) and deposits that value at the beginning or end of the considered range. In fact, Cocktail Shaker sort is really just Bubble Sort but in both directions.

The "audibilization" of this sort is particularly interesting, because it's simple to understand without knowing the underlying math and logic:

```
class CocktailShakerSort
{
static void Sort(int[] array)
{
bool isSwapped = true;
int start = 0;
int end = array.Length;
while (isSwapped == true)
{
//Reset this flag. It is possible for this to be true from a prior iteration.
isSwapped = false;
//Do a bubble sort on this array, from low to high. If something changed, make isSwapped true.
for (int i = start; i < end - 1; ++i)
{
if (array[i] > array[i + 1])
{
int temp = array[i];
array[i] = array[i + 1];
array[i + 1] = temp;
isSwapped = true;
}
}
//If no swaps are made, the array is sorted.
if (isSwapped == false)
break;
//We need to reset the isSwapped flag for the high-to-low pass
isSwapped = false;
//The item we just moved is in its rightful place, so we no longer need to consider it unsorted.
end = end - 1;
//Now we bubble sort from high to low
for (int i = end - 1; i >= start; i--)
{
if (array[i] > array[i + 1])
{
int temp = array[i];
array[i] = array[i + 1];
array[i + 1] = temp;
isSwapped = true;
}
}
//Finally, we need to increase the starting point for the next low-to-high pass.
start = start + 1;
}
}
public static void Main()
{
int[] array = { 15, 10, 83, 5, 7, 42, 65, 50, 58, 71, 61 };
CommonFunctions.PrintInitial(array);
Sort(array);
CommonFunctions.PrintFinal(array);
Console.ReadKey();
}
}
```

You may have heard before that Bubble Sort's complexities for all cases are *O(n ^{2})*. Cocktail Shaker Sort, being a direct derivative of Bubble Sort, is not much better; the average and worst-case complexities do not improve, and only the best case scenario (where the list is already sorted) becomes

About the only good thing Cocktail Shaker Sort has going for it is a space complexity of constant value, *O(1)*. But that's not very useful in the real world. In short, Cocktail Shaker Sort is not a valuable implementation of sorting for anything other than educational or theoretical problems.

Cocktail Shaker Sort is an easy-to-understand, simple-to-implement derivative of Bubble Sort. However, it's not a terribly useful sort in the real world, as it takes too long to do much of anything. Plus, he makes a drink that'll burn your eyeballs out. Don't say I didn't warn you.

Don't forget to check out the sample project over on GitHub!

Happy Coding!

]]>Quick Sort is the consummate overachiever.

Graduated first in his class, runs a successful business, owns a boat, married to a brilliant accountant, with two beautiful children. He does not slow down; he does everything fast and thoroughly. Keeping up with his family is quite the endeavor. When he picks something to get done, it gets DONE.

Sometimes, though, he wonders. He wonders if maybe there's more to life than climbing the org chart, buying soulless things, or making money. He wonders if maybe, just maybe, he could slow down and enjoy the scenery for once. And then he decides that's for wimps and goes back to working all hours of the night.

**Created By:**C. A. R. "Tony" Hoare (1959)**Type:****E**xchange**Stable?**No**Best-Case:***O(n log n)***Average-Case:***O(n log n)***Worst-Case:***O(n*^{2})**Space Complexity:***O(n)***Sample Project:**Over on GitHub

- SELECT a pivot point. (Our implementation selects the last number in the collection).
- REORDER the collection such that all values less than the pivot are before the pivot, and all values greater than the pivot are after it.
- RECURSIVE CONTINUE: Return to Step 1, selecting a new pivot in each of the divided higher and lower sections, until the array is sorted.

The critical thing Quick Sort does is select a pivot point, but different varieties do this differently. In the above animation (and the below implementation), the first pivot point is merely the last item in the collection, and it continues to pick the last item in each "partition" caused by the sort as a pivot point.

Reader James Curran also contributed another visualization of this sort:

Finally, check out this audibilization on YouTube:

```
class QuickSort
{
static int Partition(int[] array, int low,
int high)
{
//1. Select a pivot point.
int pivot = array[high];
int lowIndex = (low - 1);
//2. Reorder the collection.
for (int j = low; j < high; j++)
{
if (array[j] <= pivot)
{
lowIndex++;
int temp = array[lowIndex];
array[lowIndex] = array[j];
array[j] = temp;
}
}
int temp1 = array[lowIndex + 1];
array[lowIndex + 1] = array[high];
array[high] = temp1;
return lowIndex + 1;
}
static void Sort(int[] array, int low, int high)
{
if (low < high)
{
int partitionIndex = Partition(array, low, high);
//3. Recursively continue sorting the array
Sort(array, low, partitionIndex - 1);
Sort(array, partitionIndex + 1, high);
}
}
public static void Main()
{
int[] array = { 72, 12, 6, 33, 81, 97, 37, 59, 52, 1, 20 };
int length = array.Length;
Console.WriteLine("QuickSort");
CommonFunctions.PrintInitial(array);
Sort(array, 0, length - 1);
CommonFunctions.PrintFinal(array);
Console.ReadKey();
}
}
```

The entire reason Quick Sort has that name is because, for the vast majority of circumstances, it is demonstrably quicker than other relatively-simple implementations. That said, there is some debate about how much quicker it is than, say, Merge Sort, which clearly means that Quick Sort must get along fabulously with his father-in-law Selection Sort, but maybe not his mother-in-law.

It would be valid, I believe, to say that Quick Sort is the simplest sorting algorithm that is actually in use today for real production code. Some of the upcoming algorithms are much more complex, but faster.

Also, apropos of nothing, the inventor of Quick Sort wrote possibly my favorite adage about coding:

"There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies. The first method is far more difficult." - C. A. R. Hoare

Quick Sort is exactly what it sounds like. It gets things sorted, as quickly as possible, by subdividing the contents of a collection around an arbitrarily-selected pivot point. It then recursively selects smaller and smaller "partitions" and orders them.

Sometimes he wishes he could slow down. Maybe he will get his chance. Someday.

Don't forget to check out the sample project over on GitHub!

Happy Coding!

]]>Unlike his elder brother Shell Sort, Comb Sort is a star athlete. He started as the quarterback for his high school football team when he was a sophomore. But more than that, he has everything he thought he could ever

]]>Comb Sort is the poster boy for the all-American child.

Unlike his elder brother Shell Sort, Comb Sort is a star athlete. He started as the quarterback for his high school football team when he was a sophomore. But more than that, he has everything he thought he could ever want, at least until recently. He's the junior prom king, the one voted "best athlete" in the yearbook, everything. Life has been easy for him so far.

Yet, something is bothering him. Something that, until recently, he couldn't describe.

He's not the smartest guy, and he knows this. His grades are mostly Cs and Ds, and he understands that that doesn't bode well for his future. His parents are high-achievers, his brother is a straight-A student, and he's... what? A star athlete? That won't last forever. What happens when he can no longer get by on physical prowess?

So, he reads. He studies. He's putting more time into making good test scores and less time into sports. It's not working yet (his last test was a C+), but he's hopeful that it will, and soon. He can't get through life on athletic skills alone. He's sorting out his life, one piece at a time.

**Created By:**Włodzimierz Dobosiewicz (1980)**Type:**Exchange**Stable?**YES**Best-Case:***O(n)***Average-Case:***O(n*^{2})**Worst-Case:***O(n*^{2})**Space Complexity:***O(1)***Sample Project:**Over on GitHub

- DETERMINE the appropriate gap size
*h*by using a set shrink factor*k*. - COMPARE each pair of elements that are
*h*distance from each other. - SWAP those elements if they are in the wrong order.
- COMPLETE a pass through the array with the selected
*h*. - SHRINK the gap size
*h*using shrink factor*k*. - IF
*h*is not 1, GOTO step 2. - CONTINUE until
*h*is 1 AND a pass through the array results in no swaps.

You can see from this animation why this algorithm got the name "Comb Sort": the comparison distance look like two prongs in a comb. You can also see that this is a not-very-effective sort: it has to do many passes through all elements in order to fully sort this list. In fact, we would most likely consider Comb Sort to be a "naive" sort, on the same level as Selection Sort.

Also check out the "audibilization" of this sort from YouTube:

Finally, reader James Curran kindly created a visualization for this sort; it looks like this:

```
class CombSort
{
static int GetNextGap(int gap)
{
//The "shrink factor", empirically shown to be 1.3
gap = (gap * 10) / 13;
if (gap < 1)
{
return 1;
}
return gap;
}
static void Sort(int[] array)
{
int length = array.Length;
int gap = length;
//We initialize this as true to enter the while loop.
bool swapped = true;
while (gap != 1 || swapped == true)
{
gap = GetNextGap(gap);
//Set swapped as false. Will go to true when two values are swapped.
swapped = false;
//Compare all elements with current gap
for (int i = 0; i < length - gap; i++)
{
if (array[i] > array[i + gap])
{
//Swap
int temp = array[i];
array[i] = array[i + gap];
array[i + gap] = temp;
swapped = true;
}
}
}
}
public static void Main()
{
int[] array = { 10, 28, 1, 55, 6, 21, 36, 3, 45, 15, 0 };
Console.WriteLine("Comb Sort");
CommonFunctions.PrintInitial(array);
Sort(array);
CommonFunctions.PrintFinal(array);
Console.ReadLine();
}
}
```

The worst case of *O(n ^{2}) *make intuitive sense, at least to me. Given that comb sort is based on bubble sort, we would expect poor time complexities for it. But the average case is interesting because it introduces a form of notation I hadn't seen before: big-omega.

Remember that the average time complexity for this algorithm is *Ω(n ^{2}/2^{p}). *This is read aloud as "big-omega of n-squared over 2 to the power of p".

This is not a great time, and because it's the best possible case on average, we can conclude that Comb Sort is not an efficient sorting algorithm.

Comb Sort is a relatively-inefficient algorithm that aims to sort a collection by comparing two elements across *h* distance, swapping them if they are out of order, and then slowly shrinking that distance. He's hoping he can get his academic life in order before his athletic skills run out. Slowly, surely, he's making that dream come true, one test at a time.

Don't forget to check out the sample project over on GitHub!

Happy Coding!

]]>He's a straight-A high school senior who really doesn't understand why he has to

]]>Shell Sort is the unassuming, quiet type. The late-teens son of high-achieving Insertion Sort and Quick Sort, Shell Sort would much rather just curl up alone with a good sci-fi/fantasy book and sip hot cocoa.

He's a straight-A high school senior who really doesn't understand why he has to be at this stupid family reunion thing. In fact, he'd much rather be home right now, reading the latest N.K. Jemisin book.

Although, Auntie Heapy's cooking is pretty good. And the family football game isn't the worst thing in the universe. And as much as he's annoyed by younger brother Comb Sort, it's really nice to have him on the same team. So it isn't all bad. Just *mostly* bad.

**Created By:**Donald Shell (1959)**Type:**Exchange/Insertion**Stable?**No**Best-Case:***O(n log n)***Worst-Case:***O(n*^{2})**Space Complexity:***O(n)***Sample Project:**Over on GitHub

- DETERMINE the size of the gap we want to use, called
*h*. - DIVIDE the main array into conceptual subarrays using elements that are
*h*distance from each other (no concrete subarrays will actually be created). - SORT those subarrays in place.
- REDUCE the gap size
*h*so as to group items closer together for sorting. - CONTINUE until a pass has been done with
*h*=1, when the list will be sorted.

This is one of the visualizations I found for Shell Sort, but it's not very clear (at least to me) what's actually happening here, so let's see if we can break it down.

The first thing you need to know is that the goal of Shell Sort is to reduce the number of moves that must be made when gap size *h* = 1. In that situation, Shell Sort becomes Insertion Sort, and Insertion Sort does very poorly if the numbers to be sorted are far away from where they should be.

Imagine we have the following data:

a_{0} |
a_{1} |
a_{2} |
a_{3} |
a_{4} |
a_{5} |
a_{6} |
a_{7} |
a_{8} |
a_{9} |
a_{10} |
a_{11} |
---|---|---|---|---|---|---|---|---|---|---|---|

43 | 18 | 91 | 6 | 29 | 62 | 30 | 81 | 79 | 52 | 7 | 51 |

Let's also say that our gap size *h* will be 5 for the first round of sorting. That means that Shell Sort will create the following theoretical subarrays:

{ a_{0}, a_{5}, a_{10} }

{ a_{1}, a_{6}, a_{11} }

{ a_{2}, a_{7} }

{ a_{3}, a_{8} }

{ a_{4}, a_{9} }

Each of those subarrays will be sorted independently of one another, resulting in a collection that looks like this:

a_{0} |
a_{1} |
a_{2} |
a_{3} |
a_{4} |
a_{5} |
a_{6} |
a_{7} |
a_{8} |
a_{9} |
a_{10} |
a_{11} |
---|---|---|---|---|---|---|---|---|---|---|---|

7 | 18 | 81 | 6 | 29 | 43 | 30 | 91 | 79 | 52 | 62 | 51 |

See how the 7 moved to the front of the array, much closer to where it should be when fully sorted?

Now let's shrink the gap size *h* to 3. Shell Sort will now use the following theoretical subarrays:

{ a_{0}, a_{3}, a_{6}, a_{9} }

{ a_{1}, a_{4}, a_{7}, a_{10} }

{ a_{2}, a_{5}, a_{8}, a_{11} }

Sorting those subarrays results in a collection that looks like this:

a_{0} |
a_{1} |
a_{2} |
a_{3} |
a_{4} |
a_{5} |
a_{6} |
a_{7} |
a_{8} |
a_{9} |
a_{10} |
a_{11} |
---|---|---|---|---|---|---|---|---|---|---|---|

6 | 18 | 43 | 7 | 29 | 51 | 30 | 62 | 79 | 52 | 91 | 81 |

Now the 6 is in front of the 7, and is in fact where it should be when the array is fully sorted. Remember that the goal here is not to fully sort the array, but to reduce the number of moves Insertion Sort must make in order to sort the array when *h* = 1. Speaking of, a pass through of this data during Insertion Sort results in, of course:

a_{0} |
a_{1} |
a_{2} |
a_{3} |
a_{4} |
a_{5} |
a_{6} |
a_{7} |
a_{8} |
a_{9} |
a_{10} |
a_{11} |
---|---|---|---|---|---|---|---|---|---|---|---|

6 | 7 | 18 | 29 | 30 | 43 | 51 | 52 | 62 | 79 | 81 | 91 |

**UPDATE (1 Aug 2019)**: Reader James Curran created another visualization of Shell Sort, and here it is:

Finally, take a look at this "audibilization" of Shell Sort from YouTube:

```
class ShellSort
{
static int Sort(int[] array)
{
int length = array.Length;
for (int h = length / 2; h > 0; h /= 2)
{
for (int i = h; i < length; i += 1)
{
int temp = array[i];
int j;
for (j = i; j >= h && array[j - h] > temp; j -= h)
{
array[j] = array[j - h];
}
array[j] = temp;
}
}
return 0;
}
public static void Main()
{
int[] array = { 53, 19, 71, 3, 66, 62, 20, 84 };
Console.WriteLine("Shell Sort");
CommonFunctions.PrintInitial(array);
Sort(array);
CommonFunctions.PrintFinal(array);
Console.ReadKey();
}
}
```

At first glance, it appears that Shell Sort actually performs *worse* than Insertion Sort, given that Insertion Sort's best case is *O(n)* and Shell Sort's best case is *O(n log n)*. But in the real world the only time Insertion Sort performs in *O(n)* time is if the list is already sorted.

As stated earlier, Shell Sort's purpose is to minimize the distance items have to move when they are being sorted by the final stage where *h* = 1. The problem when trying to determine Shell Sort's time complexity is that such complexity depends entirely on what the implementation chooses for the values of *h*.

A final note: the implementation above actually has a time complexity of *O(n ^{2})*, and is used for simplicity and not fit for production.

Shell Sort is mainly an improvement on Insertion Sort, by making long-distance moves less common when sorting the array. He'd much rather be home with a good book, but the family reunion isn't awful. Sometimes.

Don't forget to check out the sample project over on GitHub!

Happy Coding!

]]>