CS 332: Algorithms: Solving Recurrences Continued The Master Theorem Introduction To Heapsort
CS 332: Algorithms: Solving Recurrences Continued The Master Theorem Introduction To Heapsort
CS 332: Algorithms: Solving Recurrences Continued The Master Theorem Introduction To Heapsort
Effort
T(n)
(1)
(1)
T(n/2)
T(n/2)
(n)
c
n 1
T (n) aT n cn n 1
T (n) aT
c
n 1
n
cn n 1
b
T(n) =
aT(n/b) + cn
a(aT(n/b/b) + cn/b) + cn
a2T(n/b2) + cna/b + cn
a2T(n/b2) + cn(a/b + 1)
a2(aT(n/b2/b) + cn/b2) + cn(a/b + 1)
a3T(n/b3) + cn(a2/b2) + cn(a/b + 1)
a3T(n/b3) + cn(a2/b2 + a/b + 1)
T (n) aT
c
n 1
n
cn n 1
b
So we have
T(n) = akT(n/bk) + cn(ak-1/bk-1 + ... + a2/b2 + a/b + 1)
For k = logb n
n = bk
T(n) = akT(1) + cn(ak-1/bk-1 + ... + a2/b2 + a/b + 1)
T (n) aT
c
n 1
n
cn n 1
b
So with k = logb n
T(n) = cn(ak/bk + ... + a2/b2 + a/b + 1)
What if a = b?
T(n) = cn(k + 1)
= cn(logb n + 1)
= (n log n)
T (n) aT
c
n 1
n
cn n 1
b
So with k = logb n
T(n) = cn(ak/bk + ... + a2/b2 + a/b + 1)
What if a < b?
T (n) aT
c
n 1
n
cn n 1
b
So with k = logb n
T(n) = cn(ak/bk + ... + a2/b2 + a/b + 1)
What if a < b?
Recall that (xk + xk-1 + + x + 1) = (xk+1 -1)/(x-1)
T (n) aT
c
n 1
n
cn n 1
b
So with k = logb n
T(n) = cn(ak/bk + ... + a2/b2 + a/b + 1)
What if a < b?
Recall that (xk + xk-1 + + x + 1) = (xk+1 -1)/(x-1)
So:
a k a k 1
a
k 1 1
k
b
b b
a b k 1 1
a b 1
1 a b
1 a b
k 1
1 a b
T (n) aT
c
n 1
n
cn n 1
b
So with k = logb n
T(n) = cn(ak/bk + ... + a2/b2 + a/b + 1)
What if a < b?
Recall that (xk + xk-1 + + x + 1) = (xk+1 -1)/(x-1)
So:
a k a k 1
a
k 1 1
k
b
b b
a b k 1 1
a b 1
1 a b
1 a b
k 1
1 a b
T (n) aT
c
n 1
n
cn n 1
b
So with k = logb n
T(n) = cn(ak/bk + ... + a2/b2 + a/b + 1)
What if a > b?
T (n) aT
c
n 1
n
cn n 1
b
So with k = logb n
T(n) = cn(ak/bk + ... + a2/b2 + a/b + 1)
What if a > b?
a k a k 1
a
k 1 1
k
b
b b
a b k 1 1
a b 1
a b
T (n) aT
c
n 1
n
cn n 1
b
So with k = logb n
T(n) = cn(ak/bk + ... + a2/b2 + a/b + 1)
What if a > b?
a k a k 1
a
k 1 1
k
b
b b
T(n) = cn (ak / bk)
a b k 1 1
a b 1
a b
T (n) aT
c
n 1
n
cn n 1
b
So with k = logb n
T(n) = cn(ak/bk + ... + a2/b2 + a/b + 1)
What if a > b?
a k a k 1
a
k 1 1
k
b
b b
T(n) = cn (ak / bk)
a b k 1 1
a b 1
a b
T (n) aT
c
n 1
n
cn n 1
b
So with k = logb n
T(n) = cn(ak/bk + ... + a2/b2 + a/b + 1)
What if a > b?
a k a k 1
a
k 1 1
k
b
b b
T(n) = cn (ak / bk)
a b k 1 1
a b 1
a b
T (n) aT
So with k = logb n
c
n 1
n
cn n 1
b
What if a > b?
a k a k 1
a
k 1 1
k
b =b cn (ak /bbk)
T(n)
a b k 1 1
a b 1
a b
T (n) aT
So with k = logb n
c
n 1
n
cn n 1
b
What if a > b?
a k a k 1
a
k 1 1
k
b =b cn (ak /bbk)
T(n)
a b k 1 1
a b 1
a b
T (n) aT
c
n 1
n
cn n 1
b
So
T (n) n log b n
n logb a
ab
ab
ab
log b a
T ( n) n
log n
f ( n )
log b a
f (n) O n log b a
f ( n) n
log b a
c 1
= (n2)
Since f(n) = O(nlog 9 - ), where =1, case 1 applies:
nlog a = nlog
b
Sorting Revisited
So far weve talked about two algorithms to
Heaps
A heap can be seen as a complete binary tree:
16
14
10
Heaps
A heap can be seen as a complete binary tree:
16
14
10
Heaps
In practice, heaps are usually implemented as
arrays:
16
14
A = 16 14 10 8
10
1 =
2
7
4
Heaps
To represent a complete binary tree as an array:
The root node is A[1]
Node i is A[i]
The parent of node i is A[i/2] (note: integer divide)
The left child of node i is A[2i]
The right child of node i is A[2i + 1]
16
14
A = 16 14 10 8
10
1 =
2
7
4
most efficiently?
Another aside: Really?
of its parent
Where is the largest element in a heap stored?
Definitions:
The height of a node in the tree = the number of edges
Heap Height
What is the height of an n-element heap?
Why?
This is nice: basic heap operations take at most
time proportional to the height of the heap
heaps
Problem: The subtree rooted at i may violate the heap
property (How?)
Action: let the value of the parent node float down so
subtree at i satisfies the heap property
What do you suppose will be the basic operation between i, l,
and r?
Heapify() Example
16
4
10
14
2
7
8
A = 16 4 10 14 7
Heapify() Example
16
4
10
14
2
7
8
A = 16 4 10 14 7
Heapify() Example
16
4
10
14
2
7
8
A = 16 4 10 14 7
Heapify() Example
16
14
10
4
2
7
8
A = 16 14 10 4
Heapify() Example
16
14
10
4
2
7
8
A = 16 14 10 4
Heapify() Example
16
14
10
4
2
7
8
A = 16 14 10 4
Heapify() Example
16
14
10
8
2
7
4
A = 16 14 10 8
Heapify() Example
16
14
10
8
2
7
4
A = 16 14 10 8
Heapify() Example
16
14
10
8
2
7
4
A = 16 14 10 8
(1) time
If the heap at i has n elements, how many
elements can the subtrees at l or r have?
Draw it
BuildHeap()
// given an unsorted array A, make A a heap
BuildHeap(A)
{
heap_size(A) = length(A);
for (i = length[A]/2 downto 1)
Heapify(A, i);
}
BuildHeap() Example
Work through example
2
14
16
8
10
Analyzing BuildHeap()
Each call to Heapify() takes O(lg n) time
There are O(n) such calls (specifically, n/2 )
Thus the running time is O(n lg n)
Is this a correct asymptotic upper bound?
Is this an asymptotically tight bound?
reasoning?
nodes of height h
CLR 7.3 uses this fact to prove that
BuildHeap() takes O(n) time
Heapsort
Given BuildHeap(), an in-place sorting
Heapify()
Repeat, always swapping A[1] for A[heap_size(A)]
Heapsort
Heapsort(A)
{
BuildHeap(A);
for (i = length(A) downto 2)
{
Swap(A[1], A[i]);
heap_size(A) -= 1;
Heapify(A, 1);
}
}
Analyzing Heapsort
The call to BuildHeap() takes O(n) time
Each of the n - 1 calls to Heapify() takes
O(lg n) time
Thus the total time taken by HeapSort()
= O(n) + (n - 1) O(lg n)
= O(n) + O(n lg n)
= O(n lg n)
Priority Queues
Heapsort is a nice algorithm, but in practice