| Algorithm | Comments |
|---|---|
| Selection | Classic naive sorting algorithm. |
| Bubble | Grossly oversold sorting algorithm. |
| Double Bubble |
Also known as the bidirectional bubble sort, this is a variant of the bubble sort which percolates elements in both directions. It is a fairly decent algorithm for small, nearly sorted lists and is used in my implementation of the Shell sort. |
| Shell | Classic meta-algorithm sorting algorithm. This implementation uses the double bubble algorithm. |
| Heap | Classic invariant property sorting algorithm. For simple implementations a heap sort is better than a quick sort, although careful implementations of the quick sort pivot selection function generally makes the quick sort a better choice in practice. |
| Quick | Classic divide-and-conquer sorting algorithm. The implementation provided uses a naive algorithm to determine the pivot point and has a pathological worst case. This package is not intended as a production quick sort implementation. |
| Type of Algorithm | Description |
|---|---|
| Naive | Naive algorithms have an unfortunate name due to the emotional connotations of the word "naive". A naive algorithm is simply the first algorithm known to be correct which doesn't fall into one of the other categories. Before an algorithm is known to be correct (that is, to provide the correct results), concern about its execution speed is irrelevant [1]. After at least one algorithm is known to be correct the primary concern is generally speed. These facts conspire to ensure the first correct algorithm is almost always the slowest known algorithm. |
| Divide-and-Conquer | A divide-and-conquer algorithm breaks the problem into two or more subproblems. The subproblems do not need to be equally sized, but the total number of (levels of) iteration of the algorithm should be proportional to log(n) instead of n. This property holds whenever the size of each subproblem is proportional to the size of the problem. If the size of one subproblem is fixed and the other subproblem is whatever is left over the number of (levels of) iteration of the algorithm is proportional to n. Finally, implementations of divide-and-conquer algorithms generally switch to a different algorithm for small enough problems where those algorithms are more efficient. |
| Invariant Property | An invariant property algorithm is based on the fact that objects with invariant properties (e.g., the heap of the heap sort) are often efficiently modified a single element at a time. The heap sort is a classic example of this. Given a heap, it takes time O(lg (n)) to insert (remove) an item to(from) the heap. It is easy to prove that the worst case performance of the heap sort is O(n lg (n)), the best of these algorithms (although quick sort can match it with a well-chosen pivot selection algorithm). As an aside, divide-and-conquer algorithms often exploit invariant properties as well. The distinction is that an algorithm such as heap sort doesn't have a divide-and-conquer aspect to it. |
| Meta-algorithm | A meta-algorithm is an algorithm which uses another algorithm efficiently. This often results in pronounced performance improvements since the meta-algorithm can often guarantee tighter restrictions on the characteristics of the data passed to the subordinate algorithm, allowing the use of more efficient but less general algorithms than could be used without the intermediatary behavior of the meta-algorithm. The Shell sort is a meta-algorithm since it guarantees that the subordinate algorithm will see arrays which are either extremely small or already nearly sorted. |
[1] In rare cases it's acceptable to use an algorithm which provides an almost-but-not-quite correct solution.
This table contains Java implementations of the six algorithms on small (ca. 100) samples of random values. On each data comparision two colored lines are drawn to indicate the "active regions" of the algorithm. These examples are large enough for the asymptotic behavior of the behavior to dominate.
To start the animation for an algorithm, click on the respective array.
| Selection | Bubble | Double Bubble |
Shell | Heap | Quick |
|---|---|---|---|---|---|
The standard references on sorting and searching algorithms are:
Several excellent books describing good software development practices
are:
Far too often developers who complain that an algorithm is "too
difficult to implement" are actually admitting that they have never
been exposed to good development practices. It's not their fault;
few academic programs recognize the difference between computer
science (which is the study of algorithms) and software engineering
(which is the study of how to use the results of computer science in
practical systems). The fields are related, but only to the same extent
as physics and electrical engineering, or biology and medicine.
These books provide a relatively painless introduction to the
practices of a software craftsman. Becoming a craftsman isn't
quite the same as becoming a good engineer, but in an ideal world
all programmers would be good craftsmen and engineers.
Good introductory books which touch on sorting algorithms include:
This page was inspired by a much simpler
animated sorting algorithms
page on Sun's
Java page.
Further Reading
The latter book is the definitive book on searching and sorting
algorithms known at the time of its publication. Since it was written
before the widespread adaption of "big-O" notation for algorithm
analysis and provides algorithms in
ISBN 0-07-013143-0
MIX assembly code, many
readers find it difficult reading.
ISBN 0-201-10331-1 and 0-201-11889-0
ISBN 0-13-721374-3
ISBN 0-13-196253-1
ISBN 0-934375-40-2
Acknowledgements
Copyright 1996 by <bgiles@coyotesong.com>.
All Rights Reserved.
Last modified: 29 March 1996
Minor modifications: 05 January 2000