Importance:
History:
Increments:
This basically means that a
list of size less than 13 should be used with spaces of 1. For a list of say
100 items, we find a value for H(X) where it’s greater than it.H(4)
being equal to 40 is too small, and in this case, H(5)
= 121 and that number is the first greater than 100. Our increment is going to
be H(X-2) or H(3) and we find, in this case it is
going to be13 than 4 than 1 [Which is basically insertion sort].
Note that this is not the
ONLY way that you can decide how you are going to space your Shell Sort
algorithm, it is just one of the many that are out there, and I found it as
being one of the easiest to comprehend and seems to work quite well for most
cases.
How it works:
Sorting times:
This algorithm is the most
efficient when the highest values are in the front of the list and smaller
values are located towards the end of it, or if the list is already in order.
In these scenarios, they are switched right off the bat, and in most other
O(n^2), like Bubble and Insertion sort, these values are going to spend a long
time moving to the right and to the left depending on which you are looking at,
so this algorithm really saves a lot of time in these cases.
Teaching:
Bibilography:
Sorting algorithms are a very
important part of Computer Science and every day life. What would we do without
them? How would we find things quickly? Isn’t it hard enough trying to find
things in the dictionary when they are in order, wouldn’t it be just pure hell
if they were out of order? Well, of course it would, and that’s one of the main
reasons Sorting Algorithms are such an important thing in our life. Having our
wonderful computer do all of the work for us is a miracle in itself. I am going
to explain in the next few lines information about Shell sort, and how its
used, how efficient it is, and a piece of sample code so you can see how it
works, and perhaps even implement it in your own code!
The Shell Sort algorithm was
invited by Donald L. Shell in 1959. It is viewed as the most efficient of the
O(n^2) class of sorting algorithms and with that, it is also
the most complicated and viewed bye some as being quite unstable. This
algorithm was invited to improve on the insertion sort algorithm, and it does
that quite well for almost every case. It works by sorting smaller sets of
data, and works its way with larger and larger lists till all of the data has
been sorted successfully. This algorithm is typically called a diminishing increment
sort because of its sequence of diminishing increments.
This algorithm makes many
passes through the list of data, and each time it does this, it sorts the
smaller sets using insertion sort. Work done by a man named Knuth experimented
with this algorithm and came up with the following formulas for the spacing of
your shell sort.
H(X) = 3 x H(X-1) + 1
H(1) = 1
H(2) = (3 x 1) + 1 = 4
H(3) = (3 x 4) + 1 = 13
H(4) = (3 x 13) + 1 = 40
H(5) = (3 x 40) + 1 = 121
H(6) = (3 x 121) + 1 = 364
This algorithm works in a
very peculiar fashion. What it does is it makes many passes to our list of
data. On the first pass, it is going to check every i-th item in the list.
Lets say for example we have a list of 100 items. In the
first pass, we are going to check x[0], x[13], x[26],
x[39], x[52], x[65], x[78] and x[91] (thinking of these as elements in an array
where 0 is the first element). It is going to look at all of these values and
sort them with Insertion Sort. On the next run, it is going to check the values
of x[1], x[14], x[27], x[40], x[53], x[66], x[79] and x[92].
I am not going to list out every combination, but it is going to do
x[0] - x[12] and every multiple of 13 there-after. Once
those little lists are sorted, we are going to choose yet another increment.
Using Knuth’s formula, we would most likely use 4 for our next. Choosing
x[0], x[4], x[8], x[12], x[16], and so on, the list is
already growing very quickly and will now be 4 lists of 25 items. Insertion
sort will be used once again to sort these tiny lists of data. Finally in the
last stage of the sort, most of our values will be in about the correct area
for their final destination, and when we run the insertion sort with an
increment of 1, it will go rather quickly because the values will not have to
move too far.
The average sort time for
Shell sort is approximately O(n^1.25) and its
worst-case is about O(n^1.5). Compared to the other O(n^2) algorithms, Shell
Sort is about 5 times as quick as Bubble Sort and about twice as quick as
Insertion Sort by itself. Shell Sort is not the quickest sorting method however;
there are examples like quick sort, merge sort and heap sort which are able to
sort lists many times faster; they are in a category of O(n
log n), they can complete the same sorting in MUCH less time. This algorithm is
very helpful when you are sorting lists which are typically less then 5000
items and it’s good for re-sorting smaller lists because most of the data is
already in order, and the algorithm will not have to do nearly as much work.
Anything much larger then that just increases exponentially and the user of the
computer will be ready to kick in their box waiting for it to complete.
This algorithm is a fairly
easy algorithm to learn, it’s not the easiest, but it’s defiantly not the
hardest. It is easy to implement and is quite efficient for its simplicity. It
is taught in most universities and used in many fields in Computer Science.
//
// Code from http://www.cise.ufl.edu/~sahni/dsaaj/enrich/c2/shell.htm
//
public class ShellSort
{
/** sort the elements a[0 : a.length - 1] using
* the shaker sort method */
public static void shellSort(Comparable [] a)
{
int incr = a.length / 2; // initial increment
while (incr >= 1)
{// insertion sort all sequences spaced by incr
for (int i = incr; i < a.length; i++)
{// insert a[i] into a[i - incr], a[i - 2*incr], ...
Comparable insertElement = a[i];
int j;
for (j = i - incr;
j >= 0 && insertElement.compareTo(a[j]) < 0;
j -= incr)
a[j + incr] = a[j];
a[j + incr] = insertElement;
}
// reduce increment by a factor of 2.2
if (incr == 2)
incr = 1; // last increment must be 1
else
incr = (int) (incr / 2.2);
}
}
}
http://ciips.ee.uwa.edu.au/~morris/Year2/PLDS210/niemann/s_shl.htm
http://linux.wku.edu/~lamonml/algor/sort/shell.html
http://epaperpress.com/sortsearch/index.html
http://www.cise.ufl.edu/~sahni/dsaaj/enrich/c2/shell.htm
Report by Alexander C. Schrepfer (University of Hawaii at Manoa)