Computer Algorithms Lecture 8 Quicksort Ch. 7

Download Report

Transcript Computer Algorithms Lecture 8 Quicksort Ch. 7

Computer Algorithms
Lecture 11
Sorting in Linear Time
Ch. 8
Some of these slides are courtesy of D. Plaisted et al, UNC and M. Nicolescu, UNR
Comparison-based Sorting
• Comparison sort
– Only comparison of pairs of elements may be used to gain order
information about a sequence.
– Hence, a lower bound on the number of comparisons will be a
lower bound on the complexity of any comparison-based sorting
algorithm.
• What sorts we have analyzed so far have been comparison sorts
• The best worst-case complexity so far is (n lg n)
– To sort n elements, comparison sorts must make (nlgn)
comparisons in the worst case
• We prove a lower bound of n lg n, (or (n lg n)) for any comparison
sort, implying that merge sort and heapsort are optimal.
Decision Tree Model
• Full binary tree: every node is either a leaf of has degree 2
• Represents the comparisons made by a sorting algorithm on an input
of a given size: models all possible execution traces
• Control, data movement, other operations are ignored
• Count only the comparisons
• Decision tree for insertion sort on three elements:
one execution trace
leaf:
node
Decision Tree Model
• All permutations on n elements must appear as one of
the leaves in the decision tree n! permutations
• Worst-case number of comparisons
– the length of the longest path from the root to a leaf
– the height of the decision tree
Decision Tree Model
• Goal: finding a lower bound on the running time on any
comparison sort algorithm
– find a lower bound on the heights of all decision trees for all
algorithms
Lemma
• Any binary tree of height h has at most 2h leaves
Proof: induction on h
Basis: h = 0  tree has one node, which is a leaf
2h = 1
Inductive step: assume true for h-1 (2h-1 leaves)
– Extend the height of the tree with one more level
– Each leaf becomes parent to two (complete binary tree) new
leaves
No. of leaves for tree of height h =
= 2  (no. of leaves for tree of height h-1)
≤ 2  2h-1
= 2h
Lower Bound for Comparison Sorts
Theorem: Any comparison sort algorithm requires (nlgn)
comparisons in the worst case.
Proof: How many leaves does the tree have?
– At least n! (each of the n! permutations of the input appears as
some leaf)  n! ≤ l
– At most 2h leaves
h


n! ≤ l ≤ 2h
h ≥ lg(n!) = (nlgn)
(3.18)
What comparison sorts are asymptotically optimal?
l leaves
Merge sort and heapsort
We can beat the (nlgn) running time if we use other operations than comparisons!
Beating the lower bound
• We can beat the lower bound if we don’t base our sort
on comparisons:
– Counting sort for keys in [0..k], k=O(n)
– Radix sort for keys with a fixed number of “digits”
– Bucket sort for random keys (uniformly distributed)
Counting Sort
• Assumption:
– The elements to be sorted are integers in the range 0 to k
• Idea:
– Determine for each input element x, the number of elements
smaller than or equal to x
– Place element x into its correct position in the output array
1
2
3
4
5
6
7
8
0
A 2 5 3 0 2 3 0 3
1
2
3
4
1
2
3
4
5
C 2 2 4 7 7 8
5
6
7
8
B 0 0 2 2 3 3 3 5
Counting Sort
1
j
n
A
Alg.: COUNTING-SORT(A, B, n, k)
0
1.
for i ← 0 to k
C
2.
do C[ i ] ← 0
1
B
3.
for j ← 1 to n
4.
do C[A[ j ]] ← C[A[ j ]] + 1
5.
C[i] contains the number of elements equal to i
6.
for i ← 1 to k
7.
do C[ i ] ← C[ i ] + C[i -1]
8.
C[i] contains the number of elements ≤ i
9.
for j ← n downto 1
10.
do B[C[A[ j ]]] ← A[ j ]
11.
C[A[ j ]] ← C[A[ j ]] - 1
k
n
CountingSort(A, B, k)
1. for i  1 to k
2.
do C[i]  0
3. for j  1 to length[A]
4.
do C[A[j]]  C[A[j]] + 1
5. for i  2 to k
6.
do C[i]  C[i] + C[i –1]
7. for j  length[A] downto 1
8.
do B[C[A[ j ]]]  A[j]
9.
C[A[j]]  C[A[j]]–1
Example
1
2
3
4
5
6
7
8
A 2 5 3 0 2 3 0 3
0
1
2
3
4
5
C 2 0 2 3 0 1
0
1
2
3
4
5
C 2 2 4 7 7 8
A[8]=3
1
2
3
4
5
6
B
7
8
1
2
3
4
5
1
B
2
3
4
5
0
0
1
6
3
4
5
C 1 2 4 5 7 8
3
4
5
6
1
7
8
3
2
3
4
5
C 1 2 4 6 7 8
7
3 3
2
2
0
0
C 2 2 4 6 7 8
A[6]=3
1
B
3
0
A[7]=0
8
A[5]=2
1
B
2
3
0
0
1
4
5
2
2
3
6
7
3 3
4
5
C 1 2 3 5 7 8
8
Example (cont.)
1
2
3
4
5
6
7
8
A 2 5 3 0 2 3 0 3
A[4]=0
1
2
3
B 0 0
0
1
4
5
2
2
3
6
7
8
5
2
3
B 0 0
0
1
4
5
6
3
4
5
C 0 2 3 4 7 8
3
4
1
5
6
7
8
2 3 3 3 5
2
3
4
5
C 0 2 3 4 7 7
7
2 3 3 3
2
2
0
C 0 2 3 5 7 8
A[3]=31
1
B 0 0
3 3
4
A[2]=5
8
A[1]=2
1
2
3
4
5
6
7
8
B 0 0 2 2 3 3 3 5
Counting-Sort (A, B, k)
CountingSort(A, B, k)
1. for i  1 to k
2.
do C[i]  0
3. for j  1 to length[A]
4.
do C[A[j]]  C[A[j]] + 1
5. for i  2 to k
6.
do C[i]  C[i] + C[i –1]
7. for j  length[A] downto 1
8.
do B[C[A[ j ]]]  A[j]
9.
C[A[j]]  C[A[j]]–1
O(k)
Stable, but not in place.
O(n)
No comparisons made:
it uses actual values of
the elements to index
into an array.
O(k)
O(n)
Overall time: (n + k)
Radix Sort
• It was used by the card-sorting
machines.
• Card sorters worked on one column at
a time.
• It is the algorithm for using the
machine that extends the technique to
multi-column sorting.
• The human operator was part of the
algorithm!
Key idea: sort on the “least significant digit” first and on the remaining
digits in sequential order. The sorting method used to sort each digit
must be “stable”.
If we start with the “most significant digit”, we’ll need extra storage.
Radix Sort
• Considers keys as numbers in a base-k number
– A d-digit number will occupy a field of d columns
• Sorting looks at one column at a time
– For a d-digit number, sort the least significant digit first
– Continue sorting on the next least significant digit, until
all digits have been sorted
– Requires only d passes through the list
An Example
Input
392
356
446
928 
631
532
495
After sorting
on LSD
After sorting
on middle
digit
After sorting
on MSD
631
392
532
495
356
446
928

928
631
532
446
356
392
495

356
392
446
495
532
631
928



Radix-Sort(A, d)
RadixSort(A, d)
1. for i  1 to d
2. do use a stable sort to sort array A on digit I
1 is the lowest order digit, d is the highest-order digit
Correctness of Radix Sort
By induction on the number of digits sorted.
Assume that radix sort works for d – 1 digits.
Show that it works for d digits.
Radix sort of d digits  radix sort of the low-order d – 1 digits
followed by a sort on digit d .
Correctness of Radix sort
• We use induction on the number d of passes through the digits
• Basis: If d = 1, there’s only one digit, trivial
• Inductive step: assume digits 1, 2, . . . , d-1 are sorted
– Now sort on the d-th digit
– If ad < bd, sort will put a before b: correct
a < b regardless of the low-order digits
– If ad > bd, sort will put a after b: correct
a > b regardless of the low-order digits
– If ad = bd, sort will leave a and b in the
same order and a and b are already sorted
on the low-order d-1 digits
Analysis of Radix Sort
• Given n numbers of d digits each, where each digit may
take up to k possible values, RADIX-SORT correctly
sorts the numbers in (d(n+k))
– One pass of sorting per digit takes (n+k) assuming that we use
counting sort
– There are d passes (for each digit)
Bucket Sort
• Assumption:
– the input is generated by a random process that distributes
elements uniformly over [0, 1)
– the discrete () uniform distribution is a discrete probability distribution
that can be characterized by saying that all values of a finite set of
possible values are equally probable.
• Idea:
–
–
–
–
Divide [0, 1) into n equal-sized buckets
Distribute the n input values into the buckets
Sort each bucket
Go through the buckets in order, listing elements in each one
• Input: A[1 . . n], where 0 ≤ A[i] < 1 for all i
• Output: elements in A sorted
• Auxiliary array: B[0 . . n - 1] of linked lists, each list initially empty
Example - Bucket Sort
1 .78
0
/
2 .17
1
.17
.12
3 .39
2
.26
.21
4 .26
3
.39
/
5 .72
4
/
6 .94
5
/
7 .21
6
.68
/
8 .12
7
.78
9 .23
8
10 .68
9
.72
/
.94
/
/
.23
/
/
Example - Bucket Sort
.12
0
.17
.23
.21
.12
.17
2
.21
.23
3
.39
/
6
.68
/
7
.72
4
/
5
/
9
.39
.68
.72
.78
.94
/
1
8
.26
.78
/
.94
/
/
.26
/
/
Concatenate the lists from
0 to n – 1 together, in order
/
Analysis
• Relies on no bucket getting too many values.
• All lines except insertion sorting take O(n) altogether.
• Intuitively, if each bucket gets a constant number of elements, it
takes O(1) time to sort each bucket  O(n) sort time for all buckets.
• We “expect” each bucket to have few elements, since the average is
1 element per bucket.
• But we need to do a careful analysis.
Summary
Non-Comparison
Based Sorts
Running Time
worst-case
Counting Sort
Radix Sort
Bucket Sort
O(n + k)
O(d(n + k'))
average-case
best-case
O(n + k)
O(d(n + k'))
O(n)
O(n + k)
O(d(n + k'))
in place
no
no
no
Counting sort assumes input elements are in range [0,1,2,..,k] and uses
array indexing to count the number of occurrences of each value.
Radix sort assumes each integer consists of d digits, and each digit is in
range [1,2,..,k'].
Bucket sort requires advance knowledge of input distribution (sorts n
numbers uniformly distributed in range in O(n) time).