Comparison of Sorting Algorithms

Introduction

This page implements six common sorting algorithms in Java. Each of these algorithms calls a common set of procedures to show a visible indication of the "active" region and to introduce a brief delay. This makes it easy for the reader to observe the characteristics of the sorting algorithm.

Algorithms

These algorithms have been documented in numerous books and are not discussed in detail here. The implementations use the standard published techniques for the basic algorithm; refinements do not modify the asymptotic performance of these algorithms.

AlgorithmComments
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.

Types of Algorithms

Type of AlgorithmDescription
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.

Java Implementations

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
(Animation of Selection Sort) (Animation of Bubble Sort) (Animation of Double Bubble Sort) (Animation of Shell Sort) (Animation of Heap Sort) (Animation of Quick Sort)
O(n2)
O(n2)
O(n2)
O(n1.25)
O(n lg(n))
O(n lg(n))[1]
[1] The asymptotic running time for quicksort assumes the use of an intelligent pivot selection algorithm.

Further Reading

The standard references on sorting and searching algorithms are:

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 MIX assembly code, many readers find it difficult reading.

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:

Acknowledgements

This page was inspired by a much simpler animated sorting algorithms page on Sun's Java page.


Copyright 1996 by <bgiles@coyotesong.com>. All Rights Reserved.
Last modified: 29 March 1996 Minor modifications: 05 January 2000