Quick Sort
Quick Sort
Quicksort
From Wikipedia, the free encyclopedia
case, it makes O(n2) comparisons, though this behavior is rare. Class Sorting algorithm
Worst case O(n2)
performance
Contents Best case O(n log n) (simple partition)
performance or O(n) (three-way partition
1 History and equal keys)
2 Algorithm Average case O(n log n)
2.1 Implementation issues performance
2.1.1 Choice of pivot Worst case space O(n) auxiliary (naive)
2.1.2 Repeated elements complexity O(log n) auxiliary (Sedgewick
1978)
2.1.3 Optimizations
2.1.4 Parallelization
3 Formal analysis
3.1 Average-case analysis using discrete probability
3.2 Average-case analysis using recurrences
3.3 Analysis of randomized quicksort
3.4 Space complexity
4 Relation to other algorithms
4.1 Selection-based pivoting
4.2 Variants
4.3 Generalization
5 See also
6 Notes
7 References
8 External links
http://en.wikipedia.org/wiki/Quicksort 1/12
2/26/2015 Quicksort - Wikipedia, the free encyclopedia
History
The quicksort algorithm was developed in 1960 by Tony Hoare while in the Soviet Union, as a visiting student at
Moscow State University. At that time, Hoare worked in a project on machine translation for the National Physical
Laboratory. He developed the algorithm in order to sort the words to be translated, to make them more easily matched to
an already-sorted Russian-to-English dictionary that was stored on magnetic tape.[2]
Quicksort gained widespread adoption, appearing, for example, in Unix as the default library sort function, hence it lent
its name to the C standard library function qsort[3] and in the reference implementation of Java. It was analyzed
extensively by Robert Sedgewick, who wrote his Ph.D. thesis about the algorithm and suggested several
improvements.[3]
Algorithm
Quicksort is a divide and conquer algorithm. Quicksort first divides a large array into two smaller sub-arrays: the low
elements and the high elements. Quicksort can then recursively sort the sub-arrays.
The base case of the recursion is arrays of size zero or one, which never need to be sorted. In pseudocode, a quicksort that
sorts elements lo through hi (inclusive) of an array A can be expressed compactly as[4]:171
Sorting the entire array is accomplished by calling quicksort(A, 1, length(A)). The partition operation is step 2
from the algorithm description above; it can be defined as:
http://en.wikipedia.org/wiki/Quicksort 2/12
2/26/2015 Quicksort - Wikipedia, the free encyclopedia
This is the in-place partition algorithm. It partitions the portion of the array between
indexes lo and hi, inclusively, by moving all elements less than A[pivotIndex]
before the pivot, and the greater elements after it. In the process it also finds the final
position for the pivot element, which it returns. It temporarily moves the pivot
element to the end of the subarray, so that it does not get in the way. Because it only
uses exchanges, the final list has the same elements as the original list. Notice that an
element may be exchanged multiple times before reaching its final place. Also, in
case of pivot duplicates in the input array, they can be spread across the right
subarray, in any order. This doesn't represent a partitioning failure, as further sorting
will reposition and finally "glue" them together.
This form of the partition algorithm is not the original form; multiple variations can
be found in various textbooks, such as versions not having the storeIndex. However,
this form is probably the easiest to understand.
Each recursive call to the combined quicksort function reduces the size of the array
being sorted by at least one element, since in each invocation the element at
storeIndex is placed in its final position. Therefore, this algorithm is guaranteed to
terminate recursion after at most n recursive calls. However, since partition reorders
elements within a partition, this version of quicksort is not a stable sort.
Implementation issues
Full example of quicksort on a
Choice of pivot random set of numbers. The
shaded element is the pivot. It is
In the very early versions of quicksort, the leftmost element of the partition would always chosen as the last element
often be chosen as the pivot element. Unfortunately, this causes worst-case behavior of the partition. However, always
on already sorted arrays, which is a rather common use-case. The problem was easily choosing the last element in the
solved by choosing either a random index for the pivot, choosing the middle index of partition as the pivot in this way
the partition or (especially for longer partitions) choosing the median of the first, results in poor performance
middle and last element of the partition for the pivot (as recommended by (O(n²)) on already sorted arrays,
Sedgewick).[5] This "median of three" rule counters the case of sorted (or reverse- or arrays of identical elements.
sorted) input, and gives a better estimate of the optimal pivot (the true median) than Since sub-arrays of sorted /
selecting any single element, when no information about the ordering of the input is identical elements crop up a lot
known. towards the end of a sorting
procedure on a large set, versions
Selecting a pivot element is also complicated by the existence of integer overflow. If of the quicksort algorithm which
the boundary indices of the subarray being sorted are sufficiently large, the naïve choose the pivot as the middle
expression for the middle index, (lo + hi)/2, will cause overflow and provide an element run much more quickly
invalid pivot index. This can be overcome by using, for example, lo + (hi-lo)/2 to than the algorithm described in
index the middle element, at the cost of more complex arithmetic. Similar issues this diagram on large sets of
arise in some other methods of selecting the pivot element. numbers.
Repeated elements
With a partitioning algorithm such as the one described above (even with one that chooses good pivot values), quicksort
exhibits poor performance for inputs that contain many repeated elements. The problem is clearly apparent when all the
input elements are equal: at each recursion, the left partition is empty (no input values are less than the pivot), and the
right partition has only decreased by one element (the pivot is removed). Consequently, the algorithm takes quadratic
time to sort an array of equal values.
To solve this problem (sometimes called the Dutch national flag problem[3]), an alternative linear-time partition routine
can be used that separates the values into three groups: values less than the pivot, values equal to the pivot, and values
greater than the pivot. (Bentley and McIlroy call this a "fat partition" and note that it was already implemented in the
http://en.wikipedia.org/wiki/Quicksort 3/12
2/26/2015 Quicksort - Wikipedia, the free encyclopedia
qsort of Version 7 Unix.[3]) The values equal to the pivot are already sorted, so only the less-than and greater-than
partitions need to be recursively sorted. In pseudocode, the quicksort algorithm becomes
The best case for the algorithm now occurs when all elements are equal (or are chosen from a small set of k ≪ n
elements). In the case of all equal elements, the modified quicksort will perform at
most two recursive calls on empty subarrays and thus finish in linear time.
Optimizations
Two other important optimizations, also suggested by Sedgewick and widely used in
practice are:[6][7]
To make sure at most O(log n) space is used, recurse first into the smaller
side of the partition, then use a tail call to recurse into the other.
Use insertion sort, which has a smaller constant factor and is thus faster on
small arrays, for invocations on small arrays (i.e. where the length is less than
a threshold k determined experimentally). This can be implemented by simply
In-place partition in action on a
stopping the recursion when less than k elements are left, leaving the entire
small list. The boxed element is
array k-sorted: each element will be at most k positions away from its final the pivot element, blue elements
position. Then, a single insertion sort pass[8]:117 finishes the sort in O(kn) are less or equal, and red elements
are larger.
time. A separate insertion sort of each small segment as they are identified
adds the overhead of starting and stopping many small sorts, but avoids
wasting effort comparing keys across the many segment boundaries, where keys will be in order due to the
workings of the quicksort process.
Parallelization
Quicksort's divide-and-conquer formulation makes it amenable to parallelization using task parallelism. The partitioning
step is accomplished through the use of a parallel prefix sum algorithm to compute an index for each array element in its
section of the partitioned array.[9] Given an array of size n, the partitioning step performs O(n) work in O(log n) time
and requires O(n) additional scratch space. After the array has been partitioned, the two partitions can be sorted
recursively in parallel. Assuming an ideal choice of pivots, parallel quicksort sorts an array of size n in O(n log n) work
in O(log² n) time using O(n) additional space.
Quicksort has some disadvantages when compared to alternative sorting algorithms, like merge sort, which complicate its
efficient parallelization. The depth of quicksort's divide-and-conquer tree directly impacts the algorithm's scalability, and
this depth is highly dependent on the algorithm's choice of pivot. Additionally, it is difficult to parallelize the partitioning
step efficiently in-place. The use of scratch space simplifies the partitioning step, but increases the algorithm's memory
footprint and constant overheads.
http://en.wikipedia.org/wiki/Quicksort 4/12
2/26/2015 Quicksort - Wikipedia, the free encyclopedia
Other more sophisticated parallel sorting algorithms can achieve even better time bounds.[10] For example, in 1991 David
Powers described a parallelized quicksort (and a related radix sort) that can operate in O(log n) time on a CRCW
PRAM with n processors by performing partitioning implicitly.[11]
Formal analysis
Average-case analysis using discrete probability
To sort an array of n distinct elements, quicksort takes O(n log n) time in expection, averaged over all n! permutations
of n elements with equal probability. Why? For a start, it is not hard to see that the partition operation takes O(n) time.
In the most unbalanced case, each time we perform a partition we divide the list into two sublists of size 0 and n − 1 (for
example, if all elements of the array are equal). This means each recursive call processes a list of size one less than the
previous list. Consequently, we can make n − 1 nested calls before we reach a list of size 1. This means that the call tree
is a linear chain of n − 1 nested calls. The ith call does O(n − i) work to do the partition, and
, so in that case Quicksort takes O(n²) time. That is the worst case: given knowledge of which
comparisons are performed by the sort, there are adaptive algorithms that are effective at generating worst-case input for
quicksort on-the-fly, regardless of the pivot selection strategy.[12]
In the most balanced case, each time we perform a partition we divide the list into two nearly equal pieces. This means
each recursive call processes a list of half the size. Consequently, we can make only log₂ n nested calls before we reach
a list of size 1. This means that the depth of the call tree is log₂ n. But no two calls at the same level of the call tree
process the same part of the original list; thus, each level of calls needs only O(n) time all together (each call has some
constant overhead, but since there are only O(n) calls at each level, this is subsumed in the O(n) factor). The result is
that the algorithm uses only O(n log n) time.
In fact, it's not necessary to be perfectly balanced; even if each pivot splits the elements with 75% on one side and 25%
on the other side (or any other fixed fraction), the call depth is still limited to , so the total running time is still
O(n log n).
So what happens on average? If the pivot has rank somewhere in the middle 50 percent, that is, between the 25th
percentile and the 75th percentile, then it splits the elements with at least 25% and at most 75% on each side. If we could
consistently choose a pivot from the two middle 50 percent, we would only have to split the list at most times
before reaching lists of size 1, yielding an O(n log n) algorithm.
When the input is a random permutation, the pivot has a random rank, and so it is not guaranteed to be in the middle 50
percent. However, when we start from a random permutation, in each recursive call the pivot has a random rank in its list,
and so it is in the middle 50 percent about half the time. That is good enough. Imagine that you flip a coin: heads means
that the rank of the pivot is in the middle 50 percent, tail means that it isn't. Imagine that you are flipping a coin over and
over until you get k heads. Although this could take a long time, on average only 2k flips are required, and the chance
that you won't get k heads after 100k flips is highly improbable (this can be made rigorous using Chernoff bounds). By
the same argument, Quicksort's recursion will terminate on average at a call depth of only . But if its average
call depth is O(log n), and each level of the call tree processes at most n elements, the total amount of work done on
average is the product, O(n log n). Note that the algorithm does not have to verify that the pivot is in the middle half—
if we hit it any constant fraction of the times, that is enough for the desired complexity.
An alternative approach is to set up a recurrence relation for the T(n) factor, the time needed to sort a list of size n. In the
http://en.wikipedia.org/wiki/Quicksort 5/12
2/26/2015 Quicksort - Wikipedia, the free encyclopedia
An alternative approach is to set up a recurrence relation for the T(n) factor, the time needed to sort a list of size n. In the
most unbalanced case, a single quicksort call involves O(n) work plus two recursive calls on lists of size 0 and n−1, so
the recurrence relation is
This is the same relation as for insertion sort and selection sort, and it solves to worst case T(n) = O(n²).
In the most balanced case, a single quicksort call involves O(n) work plus two recursive calls on lists of size n/2, so the
recurrence relation is
The outline of a formal proof of the O(n log n) expected time complexity follows. Assume that there are no duplicates
as duplicates could be handled with linear time pre- and post-processing, or considered cases easier than the analyzed.
When the input is a random permutation, the rank of the pivot is uniform random from 0 to n − 1. Then the resulting
parts of the partition have sizes i and n − i − 1, and i is uniform random from 0 to n − 1. So, averaging over all possible
splits and noting that the number of comparisons for the partition is n − 1, the average number of comparisons over all
permutations of the input sequence can be estimated accurately by solving the recurrence relation:
This means that, on average, quicksort performs only about 39% worse than in its best case. In this sense it is closer to
the best case than the worst case. Also note that a comparison sort cannot use less than log₂(n!) comparisons on average
to sort n items (as explained in the article Comparison sort) and in case of large n, Stirling's approximation yields
log₂(n!) ≈ n(log₂ n − log₂ e), so quicksort is not much worse than an ideal comparison sort. This fast average
runtime is another reason for quicksort's practical dominance over other sorting algorithms.
To each execution of quicksort corresponds the following binary search tree (BST): the initial pivot is the root node; the
pivot of the left half is the root of the left subtree, the pivot of the right half is the root of the right subtree, and so on. The
number of comparisons of the execution of quicksort equals the number of comparisons during the construction of the
BST by a sequence of insertions. So, the average number of comparisons for randomized quicksort equals the average
cost of constructing a BST when the values inserted form a random permutation.
Consider a BST created by insertion of a sequence of values forming a random permutation. Let C
denote the cost of creation of the BST. We have , where is an binary random variable expressing
whether during the insertion of there was a comparison to .
http://en.wikipedia.org/wiki/Quicksort 6/12
2/26/2015 Quicksort - Wikipedia, the free encyclopedia
Fix i and j<i. The values , once sorted, define j+1 intervals. The core structural observation is that is
compared to in the algorithm if and only if falls inside one of the two intervals adjacent to .
Space complexity
The space used by quicksort depends on the version used.
The in-place version of quicksort has a space complexity of O(log n), even in the worst case, when it is carefully
implemented using the following strategies:
Quicksort with in-place and unstable partitioning uses only constant additional space before making any recursive call.
Quicksort must store a constant amount of information for each nested recursive call. Since the best case makes at most
O(log n) nested recursive calls, it uses O(log n) space. However, without Sedgewick's trick to limit the recursive calls,
in the worst case quicksort could make O(n) nested recursive calls and need O(n) auxiliary space.
From a bit complexity viewpoint, variables such as lo and hi do not use constant space; it takes O(log n) bits to index
into a list of n items. Because there are such variables in every stack frame, quicksort using Sedgewick's trick requires
O((log n)²) bits of space. This space requirement isn't too terrible, though, since if the list contained distinct elements, it
would need at least O(n log n) bits of space.
Another, less common, not-in-place, version of quicksort uses O(n) space for working storage and can implement a
stable sort. The working storage allows the input array to be easily partitioned in a stable manner and then copied back to
the input array for successive recursive calls. Sedgewick's optimization is still appropriate.
The most direct competitor of quicksort is heapsort. Heapsort's worst-case running time is always O(n log n). But,
heapsort is assumed to be on average somewhat slower than standard in-place quicksort. This is still debated and in
research, with some publications indicating the opposite.[14][15] Introsort is a variant of quicksort that switches to
heapsort when a bad case is detected to avoid quicksort's worst-case running time.
Quicksort also competes with mergesort, another recursive sort algorithm but with the benefit of worst-case O(n log n)
running time. Mergesort is a stable sort, unlike standard in-place quicksort and heapsort, and can be easily adapted to
operate on linked lists and very large lists stored on slow-to-access media such as disk storage or network attached
storage. Although quicksort can easily be implemented as a stable sort using linked lists, it will often suffer from poor
pivot choices without random access. The main disadvantage of mergesort is that, when operating on arrays, efficient
implementations require O(n) auxiliary space, whereas the variant of quicksort with in-place partitioning and tail
recursion uses only O(log n) space. (Note that when operating on linked lists, mergesort only requires a small, constant
amount of auxiliary storage.)
Bucket sort with two buckets is very similar to quicksort; the pivot in this case is effectively the value in the middle of the
value range, which does well on average for uniformly distributed inputs.
Selection-based pivoting
A selection algorithm chooses the kth smallest of a list of numbers; this is an easier problem in general than sorting. One
simple but effective selection algorithm works nearly in the same manner as quicksort, and is accordingly known as
quickselect. The difference is that instead of making recursive calls on both sublists, it only makes a single tail-recursive
call on the sublist which contains the desired element. This change lowers the average complexity to linear or O(n) time,
which is optimal for selection, but worst-case time is still O(n2).
A variant of quickselect, the median of medians algorithm, chooses pivots more carefully, ensuring that the pivots are
near the middle of the data (between the 30th and 70th percentiles), and thus has guaranteed linear time – worst-case
O(n). This same pivot strategy can be used to construct a variant of quickselect (median of medians quicksort) with
worst-case O(n) time. However, the overhead of choosing the pivot is significant, so this is generally not used in practice.
More abstractly, given a worst-case O(n) selection algorithm, one can use it to find the ideal pivot (the median) at every
step of quicksort, producing a variant with worst-case O(n log n) running time. In practical implementations this variant
is considerably slower on average, but it is of theoretical interest, showing how an optimal selection algorithm can yield
an optimal sorting algorithm.
Variants
Multi-pivot quicksort
Instead of partitioning into two subarrays using a single pivot, partition into some s number of subarrays using
s − 1 pivots. While the dual-pivot case (s = 3) was considered by Sedgewick and others already in the mid-1970s,
the resulting algorithms were not faster in practice than the "classical" quicksort.[16] However, a version of dual-
pivot quicksort developed by Yaroslavskiy in 2009[17] turned out to be fast enough to warrant implementation in
Java 7, as the standard algorithm to sort arrays of primitives (sorting arrays of objects is done using Timsort).[18]
Balanced quicksort
Choose a pivot likely to represent the middle of the values to be sorted, and then follow the regular quicksort
algorithm.
External quicksort
The same as regular quicksort except the pivot is replaced by a buffer. First, read the M/2 first and last elements
into the buffer and sort them. Read the next element from the beginning or end to balance writing. If the next
http://en.wikipedia.org/wiki/Quicksort 8/12
2/26/2015 Quicksort - Wikipedia, the free encyclopedia
element is less than the least of the buffer, write it to available space at the beginning. If greater than the greatest,
write it to the end. Otherwise write the greatest or least of the buffer, and put the next element in the buffer. Keep
the maximum lower and minimum upper keys written to avoid resorting middle elements that are in order. When
done, write the buffer. Recursively sort the smaller partition, and loop to sort the remaining partition. This is a kind
of three-way quicksort in which the middle partition (buffer) represents a sorted subarray of elements that are
approximately equal to the pivot.
Generalization
Richard Cole and David C. Kandathil, in 2004, discovered a one-parameter family of sorting algorithms, called partition
sorts, which on average (with all input orderings equally likely) perform at most comparisons (close to
the information theoretic lower bound) and operations; at worst they perform comparisons
(and also operations); these are in-place, requiring only additional space. Practical efficiency and smaller
variance in performance were demonstrated against optimised quicksorts (of Sedgewick and Bentley-McIlroy).[20]
See also
Introsort
Flashsort
Notes
1. ^ Skiena, Steven S. (2008). The Algorithm Design Manual (http://books.google.com/books?id=7XUSn0IKQEgC). Springer.
http://en.wikipedia.org/wiki/Quicksort 9/12
2/26/2015 Quicksort - Wikipedia, the free encyclopedia
1. ^ Skiena, Steven S. (2008). The Algorithm Design Manual (http://books.google.com/books?id=7XUSn0IKQEgC). Springer.
p. 129. ISBN 978-1-84800-069-8.
2. ^ Shustek, L. (2009). "Interview: An interview with C.A.R. Hoare". Comm. ACM 52 (3): 38–41. doi:10.1145/1467247.1467261
(https://dx.doi.org/10.1145%2F1467247.1467261).
3. ^ a b c d Bentley, Jon L.; McIlroy, M. Douglas (1993). "Engineering a sort function"
(http://citeseer.ist.psu.edu/viewdoc/summary?doi=10.1.1.14.8162). Software—Practice and Experience 23 (11): 1249–1265.
doi:10.1002/spe.4380231105 (https://dx.doi.org/10.1002%2Fspe.4380231105).
4. ^ Cormen, Thomas H.; Leiserson, Charles E., Rivest, Ronald L., Stein, Clifford (2009) [1990]. Introduction to Algorithms (3rd
ed.). MIT Press and McGraw-Hill. ISBN 0-262-03384-4.
5. ^ a b Sedgewick, Robert (1 September 1998). Algorithms In C: Fundamentals, Data Structures, Sorting, Searching, Parts 1-4
(http://books.google.com/books?id=ylAETlep0CwC) (3 ed.). Pearson Education. ISBN 978-81-317-1291-7. Retrieved
27 November 2012.
6. ^ qsort.c in GNU libc: [1] (http://www.cs.columbia.edu/~hgs/teaching/isp/hw/qsort.c), [2]
(http://repo.or.cz/w/glibc.git/blob/HEAD:/stdlib/qsort.c)
7. ^ http://www.ugrad.cs.ubc.ca/~cs260/chnotes/ch6/Ch6CovCompiled.html
8. ^ Jon Bentley (1999). Programming Pearls. Addison-Wesley Professional.
9. ^ Umut A. Acar, Guy E Blelloch, Margaret Reid-Miller, and Kanat Tangwongsan, Quicksort and Sorting Lower Bounds
(http://www.cs.cmu.edu/afs/cs/academic/class/15210-s13/www/lectures/lecture19.pdf), Parallel and Sequential Data Structures
and Algorithms. 2013.
10. ^ Miller, Russ; Boxer, Laurence (2000). Algorithms sequential & parallel: a unified approach (http://books.google.com/books?
id=dZoZAQAAIAAJ). Prentice Hall. ISBN 978-0-13-086373-7. Retrieved 27 November 2012.
11. ^ David M. W. Powers, Parallelized Quicksort and Radixsort with Optimal Speedup (http://citeseer.ist.psu.edu/327487.html),
Proceedings of International Conference on Parallel Computing Technologies. Novosibirsk. 1991.
12. ^ McIlroy, M. D. (1999). "A killer adversary for quicksort". Software: Practice and Experience 29 (4): 341–237.
doi:10.1002/(SICI)1097-024X(19990410)29:4<341::AID-SPE237>3.3.CO;2-I
(https://dx.doi.org/10.1002%2F%28SICI%291097-024X%2819990410%2929%3A4%3C341%3A%3AAID-
SPE237%3E3.3.CO%3B2-I).
13. ^ Sedgewick, R. (1978). "Implementing Quicksort programs". Comm. ACM 21 (10): 847–857. doi:10.1145/359619.359631
(https://dx.doi.org/10.1145%2F359619.359631).
14. ^ Hsieh, Paul (2004). "Sorting revisited." (http://www.azillionmonkeys.com/qed/sort.html). www.azillionmonkeys.com.
Retrieved 26 April 2010.
15. ^ MacKay, David (1 December 2005). "Heapsort, Quicksort, and Entropy"
(http://users.aims.ac.za/~mackay/sorting/sorting.html). users.aims.ac.za/~mackay. Retrieved 26 April 2010.
16. ^ Wild, Sebastian; Nebel, Markus E. (2012). Average case analysis of Java 7's dual pivot quicksort. European Symposium on
Algorithms. arXiv:1310.7409 (https://arxiv.org/abs/1310.7409).
17. ^ http://permalink.gmane.org/gmane.comp.java.openjdk.core-libs.devel/2628
18. ^ "Arrays" (http://docs.oracle.com/javase/7/docs/api/java/util/Arrays.html#sort%28byte%5B%5D%29). Java Platform SE 7.
Oracle. Retrieved 4 September 2014.
19. ^ David M. W. Powers, Parallel Unification: Practical Complexity (http://david.wardpowers.info/Research/AI/papers/199501-
ACAW-PUPC.pdf), Australasian Computer Architecture Workshop, Flinders University, January 1995
20. ^ Richard Cole, David C. Kandathil: "The average case analysis of Partition sorts" (http://www.cs.nyu.edu/cole/papers/part-
sort.pdf), European Symposium on Algorithms, 14–17 September 2004, Bergen, Norway. Published: Lecture Notes in
Computer Science 3221, Springer Verlag, pp. 240-251.
References
http://en.wikipedia.org/wiki/Quicksort 10/12
2/26/2015 Quicksort - Wikipedia, the free encyclopedia
External links
Animated Sorting Algorithms: Quick Sort (http://www.sorting- The Wikibook Algorithm
algorithms.com/quick-sort) – graphical demonstration and discussion of implementation has a page
on the topic of: Quicksort
quick sort
Animated Sorting Algorithms: 3-Way Partition Quick Sort (http://www.sorting-algorithms.com/quick-sort-3-way)
– graphical demonstration and discussion of 3-way partition quick sort
Interactive Tutorial for Quicksort (http://pages.stern.nyu.edu/~panos/java/Quicksort/index.html)
Quicksort applet (http://www.yorku.ca/sychen/research/sorting/index.html) with "level-order" recursive calls to
http://en.wikipedia.org/wiki/Quicksort 11/12
2/26/2015 Quicksort - Wikipedia, the free encyclopedia
http://en.wikipedia.org/wiki/Quicksort 12/12