Data Structures and Algorithms (10)
BITS Pilani
Hyderabad Campus
Queue
“Queue” is the fancy name for waiting in line
Bus
Stop
BITS Pilani, Hyderabad Campus
Problem – Queue in Hospital
Patients waiting for help in Emergency Room
Give priority to
Severely wounded
Bleading
…
the ones with crash !!!
BITS Pilani, Hyderabad Campus
Problem - Queue in Operating System
Processes waiting for services
Give priority to
I/O bound
Interrups
Eg. small jobs(1page print) may be given priority over
large jobs (100pages) …
BITS Pilani, Hyderabad Campus
Priority Queue
Priority Queue is a data structure allowing at least the
following two operations:
insert same like enqueue in nonpriority queues
deleteMin (/deleteMax) is the priority queue equivalent of
queue’s dequeu operation (i.e. find and remove the element
with minimum (/maximum) priority)
Efficient implementation of priority queue ADTs
Uses and implementation of priority queues
BITS Pilani, Hyderabad Campus
Priority Queues
Queue:
– First in, first out
– First to be removed: First to enter
Priority Queue:
– First in, highest (/lowest) priority element out
– First to be removed: element with highest (/lowest)
priority
– Operations: Insert(), Remove-top()
BITS Pilani, Hyderabad Campus
Applications
• Process scheduling
– Give CPU resources to most urgent task
• Communications
– Send most urgent message first
• Event-driven simulation
– Pick next event (by time) to be simulated
Priority Queue implementations
Number of different priority categories is known
One queue for each priority
Algorithm
enqueue P1 a1 a4
– put in to proper queue
P2 b3 b1 b27 b3 b3
dequeue
– get from P1 first P3 c6 c4 c9
– then get from P2
..
– then get from P3 .
– …
P123 7 12 41
– then get from P123
BITS Pilani, Hyderabad Campus
Priority Queue implementations
Number of different priority categories is unknown
One queue for each priority
P1 a1 a4 Algorithm
enqueue
P2 b3 b1 b27 b3 b3 – put in to proper queue
dequeue
P3 c6 c4 c9
– get from P1 first
..
. – then get from P2
– then get from P3
P123 7 12 41 – …
– then get from P123
BITS Pilani, Hyderabad Campus
Types of priority queues
• Ascending priority queue
– Removal of minimum-priority element
– Remove-top(): Removes element with min priority
• Descending priority queue
– Removal of maximum-priority element
– Remove-top(): Removes element with max priority
Generalizing queues and stacks
Priority queues generalize normal queues and stacks
Priority set by time of insertion
Stack: Descending priority queue
Queue (normal): Ascending priority queue
Priority Queue implementation(2)
Sorted linked-list, with head pointer
Insert()
– Search for appropriate place to insert
– O(n)
Remove()
– Remove first in list
– O(1)
Priority Queue implementation(3)
Unsorted linked-list, with head pointer
Insert()
– Insert at the end of linked list
– O(1)
Remove()
– Search for the element (e) with min or max priority
– Remove element (e)
– O(n)
Priority Queue implementation(3)
Heap: Almost-full binary tree with heap property
Almost full:
– Balanced (all leaves at max height h or at h-1)
– All leaves to the left
Heap property: Parent >= children (descending)
– True for all nodes in the tree
– Note this is very different from binary search tree (BST)
Heap Examples
24
16 15
10 3 11 12
4 2 1
Heap or not?
Heap
Heap Examples
24
16 15
10 3 17 12
4 2 1
Heap or not?
Not Heap
(does not maintain heap property)
(17 > 15)
Heap Examples
24
16 15
10 3 11 12
4 2
1
Heap or not?
Not Heap
(balanced, but leaf with priority 1 is not in place)
Representing heap in an array
Representing an almost-complete binary tree
For parent in index i (i >= 0)
– Left child in: i*2 + 1
– Right child in: i*2 + 2
From child to parent:
– Parent of child c in: (c-1)/2
Example
0
24
1 2
16 4 13
3 5 6
14 3 11 12
4 2 1
7 8 9
In the array:
24 16 13 14 3 11 12 4 2 1
Index: 0 1 2 3 4 5 6 7 8 9
Heap property
• Heap property: parent priority >= child
– For all nodes
• Any sub-tree has the heap property
– Thus, root contains max-priority item
• Every path from root to leaf is descending
– This does not mean a sorted array
– In the array:
24 16 13 14 3 11 12 4 2 1
Maintaining heap property (heapness)
Remove-top():
Get root
Somehow fix heap to maintain heapness
Insert()
Put item somewhere in heap
Somehow fix the heap to maintain heapness
Remove-top(array-heap h)
1. if h.length = 0 // num of items is 0
2. return NIL
3. t h[0]
4. h[0] h[h.length-1] // last leaf
5. h.length h.length – 1
6. heapify_down(h, 0) // see next
7. return t
Heapify_down()
Takes an almost-correct heap, fixes it
Input: root to almost-correct heap, r
Assumes: Left subtree of r is heap
Right subtree of r is heap
but r maybe < left or right roots
Key operation: interchange r with largest child.
Repeat until in right place, or leaf.
Remove-top() example:
0
24
1 2
16 4 13
3 5 6
14 3 11 12
4 2 1
7 8 9
In the array:
24 16 13 14 3 11 12 4 2 1
Index: 0 1 2 3 4 5 6 7 8 9
Remove-top() example:
0
Out: 24 1
1 2
16 4 13
3 5 6
14 3 11 12
4 2
7 8 9
In the array:
1 16 13 14 3 11 12 4 2
Index: 0 1 2 3 4 5 6 7 8 9
Remove-top() example:
0
16
1 2
1 4 13
3 5 6
14 3 11 12
4 2
7 8 9
In the array:
16 1 13 14 3 11 12 4 2
Index: 0 1 2 3 4 5 6 7 8 9
Remove-top() example:
0
16
1 2
14 4 13
3 5 6
1 3 11 12
4 2
7 8 9
In the array:
16 14 13 1 3 11 12 4 2
Index: 0 1 2 3 4 5 6 7 8 9
Remove-top() example:
0
16
1 2
14 4 13
3 5 6
4 3 11 12
1 2
7 8 9
In the array:
16 14 13 4 3 11 12 1 2
Index: 0 1 2 3 4 5 6 7 8 9
Heapify_down(heap-array h, index i)
1. l LEFT(i) // 2*i+1
2. r RIGHT(i) // 2*i+2
3. if l < h.length // left child exists
4. if h[l] > h[r]
5. largest l
6. else largest r
7. if h[largest] > h[i] // child > parent
8. swap(h[largest],h[i])
9. Heapify_down(h,largest) // recursive
Remove-top() Complexity
Removal of root – O(1)
Heapify_down() – O(height of tree)
O(log n)
Remove-top() - O(log n)
Insert(heap-array h, item t)
Insertion works in a similar manner
We put the new element at the end of array
Exchange with ancestors to maintain heapness
If necessary.
Repeatedly.
h[h.length] t
h.length h.length + 1
Heapify_up(h, h.length) // see next
Insert() example:
0
In: 15 24
1 2
16 4 13
3 5 6
14 3 11 12
4 2 1
7 8 9
In the array:
24 16 13 14 3 11 12 4 2 1
Index: 0 1 2 3 4 5 6 7 8 9
Insert() example:
0
24
1 2
16 4 13
3 5 6
14 3 11 12
4 2 1 15
7 8 9 10
In the array:
24 16 13 14 3 11 12 4 2 1 15
Index: 0 1 2 3 4 5 6 7 8 9 10
Insert() example:
0
24
1 2
16 4 13
3 5 6
14 15 11 12
4 2 1 3
7 8 9 10
In the array:
24 16 13 14 15 11 12 4 2 1 3
Index: 0 1 2 3 4 5 6 7 8 9 10
Heapify_up(heap-array h, index i)
1. p PARENT(i) // floor( (i-1)/2 )
2. if p < 0
3. return // we are done
4. if h[i] > h[p] // child > parent
5. swap(h[p],h[i])
6. Heapify_up(h,p) // recursive
Insert() Complexity
Insertion at end – O(1)
Heapify_up() – O(height of tree)
O(log n)
Insert() - O(log n)
Priority queue as heap as binary tree in
array
Complexity is O(log n)
Both insert() and remove-top()
Must pre-allocate memory for all items
Can be used as efficient sorting algorithm
Heapsort()
Heapsort(array a)
1. h new array of size a.length
2. for i1 to a.length
3. insert(h, a[i]) // heap insert
4. i 1
5. while not empty(h)
6. a[i] remove-top(h) // heap op.
7. i i+1
Complexity: O(n log n)
Building a heap
• Use MaxHeapify to convert an array A into a max-heap.
• How?
• Call MaxHeapify on each element in a bottom-up
manner.
BuildMaxHeap(A)
BuildMaxHeap(A)
1. heap-size[A]
1. heap-size[A] length[A]
length[A]
2. for ii
2. for length[A]/2
length[A]/2 downto
downto 11
3.
3. do
do MaxHeapify(A,
MaxHeapify(A, i)i)
BITS Pilani, Hyderabad Campus
BuildMaxHeap – Example
Input Array:
24 21 23 22 36 29 30 34 28 27
Initial Heap:
(not max-heap) 24
21 23
22 36 29 30
34 28 27
BITS Pilani, Hyderabad Campus
Data Structure Binary Heap
• Array viewed as a nearly complete binary tree.
– Physically – linear array.
– Logically – binary tree, filled on all levels (except lowest.)
• Map from array elements to tree nodes and vice versa
– Root – A[1]
– Left[i] – A[2i]
– Right[i] – A[2i+1]
– Parent[i] – A[i/2]
• length[A] – number of elements in array A.
• heap-size[A] – number of elements in heap stored in A.
– heap-size[A] length[A]
BITS Pilani, Hyderabad Campus
Heap Property (Max and Min)
• Max-Heap
– For every node excluding the root,
value is at most that of its parent: A[parent[i]] A[i]
• Largest element is stored at the root.
• In any subtree, no values are larger than the value stored at subtree
root.
• Min-Heap
– For every node excluding the root,
value is at least that of its parent: A[parent[i]] A[i]
• Smallest element is stored at the root.
• In any subtree, no values are smaller than the value stored at subtree
root
BITS Pilani, Hyderabad Campus
Heaps – Example
26 24 20 18 17 19 13 12 14 11 Max-heap as an
array.
1 2 3 4 5 6 7 8 9 10
Max-heap as a binary
tree.
26
24 20
18 17 19 13
12 14 11 Last row filled from left to right.
BITS Pilani, Hyderabad Campus
Height
• Height of a node in a tree: the number of edges on the
longest simple downward path from the node to a leaf.
• Height of a tree: the height of the root.
• Height of a heap: lg n
– Basic operations on a heap run in O(lg n) time
BITS Pilani, Hyderabad Campus
Heaps in Sorting
• Use max-heaps for sorting.
• The array representation of max-heap is not sorted.
• Steps in sorting
– Convert the given array of size n to a max-heap (BuildMaxHeap)
– Swap the first and last elements of the array.
• Now, the largest element is in the last position – where it belongs.
• That leaves n – 1 elements to be placed in their appropriate
locations.
• However, the array of first n – 1 elements is no longer a max-heap.
• Float the element at the root down one of its subtrees so that the
array remains a max-heap (MaxHeapify)
• Repeat step 2 until the array is sorted.
BITS Pilani, Hyderabad Campus
Heap Characteristics
• Height = lg n
• No. of leaves = n/2
• No. of nodes of
height h n/2h+1
BITS Pilani, Hyderabad Campus
Prove that there are at most nodes of height h in an n element heap.
BITS Pilani, Hyderabad Campus
BITS Pilani, Hyderabad Campus
BITS Pilani, Hyderabad Campus
BITS Pilani, Hyderabad Campus
Maintaining the heap property
• Suppose two subtrees are max-heaps,
but the root violates the max-heap
property.
• Fix the offending node by exchanging the value at the node with the
larger of the values at its children.
– May lead to the subtree at the child not being a heap.
• Recursively fix the children until all of them satisfy the max-heap
property.
BITS Pilani, Hyderabad Campus
MaxHeapify – Example
MaxHeapify(A, 2)
26
24
14 20
18
14
24 17 19 13
12 14
14
18 11
BITS Pilani, Hyderabad Campus
Procedure MaxHeapify
MaxHeapify(A,
MaxHeapify(A,i)i)
1.1. l lleft(i)
left(i) Assumption:
2.2. rr right(i)
right(i) Left(i) and Right(i) are
3.3. ififl lheap-size[A]
heap-size[A]andandA[l]
A[l]>>A[i]
A[i] max-heaps.
4.4. then largest
thenlargest l l
5.5. else largest
elselargest i i
6.6. ififrrheap-size[A]
heap-size[A]and
andA[r]
A[r]>>A[largest]
A[largest]
7.7. then largest
thenlargest rr
largest i i
8.8. ififlargest
9.9. then thenexchange
exchangeA[i]A[i]
A[largest]
A[largest]
10.
10. MaxHeapify(A,
MaxHeapify(A,largest)
largest)
BITS Pilani, Hyderabad Campus
Running Time for MaxHeapify
MaxHeapify(A,
MaxHeapify(A,i)i)
1. l l
1. left(i)
left(i)
2. rr
2. right(i)
right(i)
3. ififl lheap-size[A]
3. heap-size[A]and
andA[l]
A[l]>>A[i]
A[i]
4.
4. then largest
thenlargest l l Time to fix node i
5.
5. else largest
elselargest i i and its children =
(1)
6. ififrrheap-size[A]
6. heap-size[A]and
andA[r]
A[r]>>A[largest]
A[largest]
7.
7. then largest
thenlargest rr
PLUS
8. largest i i
8. ififlargest
9.
9. then thenexchange A[i]
exchangeA[i] A[largest]
A[largest] Time to fix the
10.
10. MaxHeapify(A,
MaxHeapify(A,largest)
largest) subtree rooted at
one of i’s children =
T(size of subree at
largest)
BITS Pilani, Hyderabad Campus
Building a heap
• Use MaxHeapify to convert an array A into a max-heap.
• How?
• Call MaxHeapify on each element in a bottom-up manner.
BuildMaxHeap(A)
BuildMaxHeap(A)
1. heap-size[A]
1. heap-size[A] length[A]
length[A]
2. for ii
2. for length[A]/2
length[A]/2 downto
downto 11
3.
3. do
doMaxHeapify(A,
MaxHeapify(A, i)i)
BITS Pilani, Hyderabad Campus
BuildMaxHeap – Example
Input Array:
24 21 23 22 36 29 30 34 28 27
Initial Heap:
(not max-heap) 24
21 23
22 36 29 30
34 28 27
BITS Pilani, Hyderabad Campus
BuildMaxHeap – Example
MaxHeapify(10/2 = 5)
MaxHeapify(4)
MaxHeapify(3) 24
36
MaxHeapify(2)
21
34
24
36 30
23
MaxHeapify(1)
28
34
24
22 36
27
21 29 30
23
34
22 28
24 27
21
BITS Pilani, Hyderabad Campus
Correctness of BuildMaxHeap
• Loop Invariant: At the start of each iteration of the for loop, each node
i+1, i+2, …, n is the root of a max-heap.
• Initialization:
– Before first iteration i = n/2
– Nodes n/2+1, n/2+2, …, n are leaves and hence roots of max-
heaps.
• Maintenance:
– By LI, subtrees at children of node i are max heaps.
– Hence, MaxHeapify(i) renders node i a max heap root (while
preserving the max heap root property of higher-numbered nodes).
– Decrementing i reestablishes the loop invariant for the next iteration.
BITS Pilani, Hyderabad Campus
Running Time of BuildMaxHeap
• Loose upper bound:
– Cost of a MaxHeapify call No. of calls to MaxHeapify
– O(lg n) O(n) = O(nlg n)
• Tighter bound:
– Cost of a call to MaxHeapify at a node depends on the height, h, of
the node – O(h).
– Height of most nodes smaller than n.
– Height of nodes h ranges from 0 to lg n.
– No. of nodes of height h is n/2h+1
BITS Pilani, Hyderabad Campus
Running Time of BuildMaxHeap
lg n
T(BuildMaxHeap) =
( NumberOfNodesAtHeight (h))O(h)
h 0
lg n
n
h 0
2 h 1 O (h)
lg n h
O n h
h 0 2
lg n h lg n
h
n 2h
O h
h 0 h 0 2
h h
O n h
h0 2
h
h 0 2
O ( n) 1/ 2
(1 1 / 2) 2
Can build a heap from an unordered array in linear time
2
Tighter Bound for T(BuildMaxHeap)
BITS Pilani, Hyderabad Campus
Thank You!!
BITS Pilani, Hyderabad Campus