a[2*i]

CSCE 210
Data Structures and Algorithms
Prof. Amr Goneid
AUC
Part 7. Priority Queues
Prof. Amr Goneid, AUC
1
Priority Queues
 Definition of Priority Queue
 The Binary Heap
 Insertion and Removal
 A Priority Queue Class
 Analysis of PQ operations
 Heapify: A Modified
Insertion Algorithm
Prof. Amr Goneid, AUC
2
1. Definition of Priority Queue
 Definition of Priority Queue
A Priority Queue (PQ) is a set with the operations:
• Insert an element
• Remove and return the smallest / largest element
 Priority queues enable us to retrieve items not by the
insertion time (as in a stack or queue), nor by a key
match (as in a dictionary), but by which item has the
highest priority of retrieval.
Prof. Amr Goneid, AUC
3
Some Applications
 Priority queues are used to maintain




schedules and calendars.
They govern who goes next in simulations of
airports, parking lots, and the like.
They serve in Bandwidth Management in
network routers.
They are used in finding shortest paths in
graphs.
One famous application is an efficient sorting
method called Heap Sort.
Prof. Amr Goneid, AUC
4
2. The Binary Heap
The Binary Heap is a common way of implementing a
PQ using an array.
The Heap is visualized as a binary tree with the
following properties:
Property (1): Partially Balanced:
The heap is as close to a complete binary tree as
possible. If there are missing leaves, they will be
in the last level at the far right.
Prof. Amr Goneid, AUC
5
The Heap as a Complete Tree
1
2
3
4
8
5
9
10
6
7
Missing Leaves
Prof. Amr Goneid, AUC
6
The Heap as a Complete Tree
Property (2): Heap Condition:
The value in each parent is ≤ the values in its
children.
1
1
2
3
3
7
4
5
7
8
9
16
7
8
5
6
18
7
9
10
Prof. Amr Goneid, AUC
7
The Heap as a Complete Tree
Property (3): The Heap array
The Heap array contains the level order traversal of the tree
1
1
2
3
3
7
4
5
7
8
9
16
7
8
5
6
18
7
9
10
Prof. Amr Goneid, AUC
8
The Heap Array
1
3
7
5
7
18
9
16
7
8
Example
 Parent at location (i), children at locations (2i) and (2i + 1)
 Parent of child at (i) is in location (i / 2)
 The heap condition is:
a[i] ≤ a[2*i] && a[i] ≤ a[2*i+1]
Prof. Amr Goneid, AUC
9
The Heap Array
 The binary heap data structure supports both
insertion and extract-min in O(log n) time
each.
 The minimum key is always at the root of the
heap.
 New keys can be inserted by placing them at
an open leaf and up-heaping the element
upwards until it sits at its proper place in the
partial order.
Prof. Amr Goneid, AUC
10
3. Insertion and Removal
Insert in The Heap
Insert array X[ ] = {2,4,6,5,3,1} into a heap
Resulting heap = {1,3,2,5,4,6}
2
2
4
2
2
4
5
6
3
insert 2
3
5
insert 4
1
6
4
1
3
5
2
4
6
insert 1
insert 6,5,3
Prof. Amr Goneid, AUC
11
Remove from The Heap
1
1
3
5
2
3
6
4
2
5
4
3
5
2
5
6
4
4
4
6
3
5
6
6
6
5
6
5
5
5
6
4
3
4
3
4
2
6
5
6
6
Input heap = {1,3,2,5,4,6}, Output = {1,2,3,4,5,6}
Prof. Amr Goneid, AUC
12
Demo: Build Max Heap
https://www.tutorialspoint.com/data_structures_algorithms
Prof. Amr Goneid, AUC
13
Demo: Max Heap Deletion
https://www.tutorialspoint.com/data_structures_algorithms
Prof. Amr Goneid, AUC
14
Demo
Heap Animation
Prof. Amr Goneid, AUC
15
4. A Priority Queue Class
// File: PQ.h
// Priority Queue header file (Minimum Heap)
/* The PQ is implemented as a minimum Heap.
The elements of the heap are of type (E).
The top of the heap will contain the smallest element.
The heap condition is that a parent is always
less than or equal to the children.
The heap is implemented as a dynamic array a[ ] with a
size specified by the class constructor.
Location a[0] is reserved for a value "itemMin" smaller
than any possible value (e.g. a negative number)
*/
Prof. Amr Goneid, AUC
16
A Priority Queue Class
#ifndef PQ_H
#define PQ_H
template <class E>
class PQ
{
public:
// Class Constructor with input size parameter
PQ (int , E );
// Class Destructor
~PQ ( );
// Member Functions
void insert (E );
// insert element into heap
E remove ( );
// remove & return the top of the heap
Prof. Amr Goneid, AUC
17
A Priority Queue Class
private:
E *a;
// Pointer to Storage Array
int MaxSize;
// Maximum Size (not including a[0])
int N;
// index of last element in the array
E itemMin;
// itemMin to be stored in a[0]
// Heap Adjustment Functions
void upheap(int k);
void downheap(int k);
};
#endif // PQ_H
#include "PQ.cpp"
Prof. Amr Goneid, AUC
18
Implementation
// File:PQ.cpp
// PQ (min Heap) Class implementation
template <class E>
PQ<E>::PQ (int mVal, E Im)
{
MaxSize = mVal;
a = new E[MaxSize+1];
N=0;
itemMin = Im;
// Minimum Heap
a[0] = itemMin ;
}
// Class Destructor
template <class E>
PQ<E>::~PQ ( )
{ delete [ ] a;}
Prof. Amr Goneid, AUC
19
Insert New Priority (Algorithm)
insert (v)
{
 Increment heap size
 insert element (v) at end (first rightmost empty leaf)
 upheap element from location (N) if necessary
}
Prof. Amr Goneid, AUC
20
UpHeap Algorithm
// Upheap element at location (k) in a minimum heap
// as long as it is less than or equal to its parent
// Assume a[0] = -∞
upheap (k)
1comp
{
copy ak into v;
while ( parent of ak >= v)
{
move parent to child’s location;
set k to point to old parent location (i.e. k ← k/2) ;
}
copy back v into ak;
}
Prof. Amr Goneid, AUC
21
Removal Algorithm
// remove and return top of the heap, then adjust heap.
remove( )
{
copy top of heap (a1) into v;
replace a1 by last element (aN);
decrement heap size;
downheap a1 to its proper location if necessary;
return v;
}
Prof. Amr Goneid, AUC
22
DownHeap Algorithm
// downheap element at (k) in the heap
downheap(k)
{
copy element ak to v;
1comp
find location (j) of its left child;
while (left child aj exists) {
if ((there is a right child) && (left child > right child))
1comp
point j to right child;
if ( v <= child ) break;
copy child to parent;
move j down to new left child;
}
copy back v to parent;
}
Prof. Amr Goneid, AUC
23
Testing PQ Class
 The binary heap is always a complete tree
 The heap array stores this tree efficiently as a
level order traversal without any gaps
 If the tree has (N) nodes, then the leftmost N
locations (apart from a[0] which contains
“itemMin”) are occupied.
 As a test for the PQ class, we will implement a
program to display the heap array as a tree
Prof. Amr Goneid, AUC
24
Testing PQ Class
 If the tree is full, its height would be h = log2(N+1)
 If the tree was complete, its height would be:
h = log2(N) + ε
where ε is a small fraction, e.g. 0.01, and x is
the ceil of x.
 A level (L) in that tree (L = 1,2,...h-1) would be
completely filled, i.e., the number of nodes would
be
nL = 2 nL-1 for (1 < L < h) with n1 = 1
 The last level (L = h) would be occupied by
1 ≤ nh ≤ 2 nh-1
Prof. Amr Goneid, AUC
25
Testing PQ Class
 If sL = index of start node in level (L) in the heap
array,
eL = index of end node in level (L) in the heap
array, then:
s1 = 1 , e1 = 1 n1 = e1-s1+1
for level 1
and
sL = eL-1 + 1 , eL = eL-1 + 2nL-1 , nL = eL-sL+1
for L = 2, 3, ... h-1
 For the last level,
eh = min (eh-1 + 2nh-1 , N)
Prof. Amr Goneid, AUC
26
Test Program
// Add the following as a public function to the PQ class definition
template <class E>
void PQ<E>::dispHeap()
{
int s = 1, e = 1, rlength, k,
Nlevels = int(ceil(log(float(N))/log(2.0)+ 0.01));
for (int level=0; level<Nlevels; level++)
{
disp_Level (Nlevels, level, s, e);
rlength = e-s+1;
s = e+1;
k = e + 2*rlength;
e = (k < N)? k : N;
}
}
Prof. Amr Goneid, AUC
27
Test Program
// Add the following as a private function to the PQ class
definition
template <class E>
void PQ<E>::disp_Level (int Nrows, int level, int s, int e)
{
int skip = int(pow(2.0, Nrows-level) - 1);
for (int i = s; i <= e; i++)
{
cout << setw(skip) << " ";
cout << setw(2) << a[i];
cout << setw(skip) << " ";
}
cout << "\n\n\n";
}
Prof. Amr Goneid, AUC
28
Test Program
// File:dispheap.cpp
// Display Heap Array in Tree Form
#include <iostream>
#include <conio.h>
#include "PQ.h"
using namespace std;
int main()
{
int e;
int x[8] = {8,2,4,6,5,3,1,7} ;
PQ<int> Heap(16, -32767);
Prof. Amr Goneid, AUC
29
Test Program
for (int i = 0; i < 8; i++)
{
cout << "Inserting " << x[i] << endl;
Heap.insert(x[i]);
Heap.dispHeap();
_getch();
}
cout <<"\n\n\n";
Prof. Amr Goneid, AUC
30
Test Program
for (i = 0; i < 8; i++)
{
e = Heap.remove();
cout << "Removing " << e << endl;
Heap.dispHeap();
_getch();
}
return 0;
}
Prof. Amr Goneid, AUC
31
Sample Output
Inserting 1
1
Removing 1
2
5
5
3
2
7 6 4 8
8 6 4 3
Removing 2
3
Inserting 7
1
5
4
7 6 8
5
7
8
2
6
4
Removing 3
4
3
5
8
7 6
Prof. Amr Goneid, AUC
32
5. Analysis of PQ Operations
 Worst case cost of insertion:
This happens when the data are inserted in
descending order in a minimum heap.
Consider inserting such sequence of (n) integers and
take T(n) to be the number of comparisons used in
the upheap process.
Let us find T(n) for each of the following sequences :
1. (1)
(a complete tree of height h = 1)
2. (3,2,1)
(a complete tree with h = 2)
3. (7,6,5,4,3,2,1)(a complete tree with h = 3)
Prof. Amr Goneid, AUC
33
Analysis of insertion
There is always a comparison of root with itemMin
so that:
n
h
Levels
T(n)
1
1
1
1*1 = 1*20 = 1
3
2
1,2
T(1) + 2*2 = 5
7
3
1,2,3
T(2) + 3*4 = 17
Prof. Amr Goneid, AUC
34
Analysis of insertion
The heap is now a full binary tree and the Worst case
number of comparisons in insertion will be:
T( n ) 
h
L 1
h
L
2

(
h

1
)
2
1

L 1
Since h  log( n  1 ) then
T ( n )  ( n  1 ) log( n  1 ) - n  O( n log n )
Prof. Amr Goneid, AUC
35
Analysis of PQ Operations
 upheap
O(h) = O(log n)
 downheap
O(h) = O(log n)
 insert (n) items
O(nlog n) or O(n)*
 remove (n) items
O(nlog n)
* see Heapify algorithm
Prof. Amr Goneid, AUC
36
6. Heapify: A Modified Insertion Algorithm
 Robert Floyd (1964) found a better way to build the heap using
a merge procedure called heapify
 Consider a node (i) in the heap with children (L) and (R).
 Consider (L) and (R) to be roots of proper heaps.
 If tree rooted at (i) violates heap property, we let the parent node
trickle down so subtree (i) satisfies the heap property.
Prof. Amr Goneid, AUC
37
Heapify Algorithm
Heapify (A[1..n], n, i)
left = 2i
right = 2i+1
if ((left ≤ n) and (A[left] > A[i])) then
max = left else max = i
if ((right ≤ n) and (A[right] > A[max])) then
max = right
if (max ≠ i) then
swap (A[i], A[max])
Heapify (A, n, max)
Notice that in the worst case Heapify will take T(n) = O(log n)
Prof. Amr Goneid, AUC
38
Building the Heap
 Given an unsorted array A, we can make it a heap using the
Heapify algorithm.
 We know that all elements at n/2+1  n are already Heaps,
so we apply Heapify only on elements at n/2  1
Build-MaxHeap (A[1..n], n)
for i = n/2 downto 1 do Heapify (A, n, i)
 Since heapify costs O(logn), so what is the advantage?
 Assuming a full tree, the number of nodes on a level (L) is 2L-1
and the total number of nodes is n = 2h-1. The worst-case
number of heap adjustments is (h-L) at level (L).
Prof. Amr Goneid, AUC
39
Analysis
 The worst case cost of insertion will be:
h
T( n )   2
L 1
L 1
h
( h  L )  h 2
L 1
L 1
h
  L 2 L 1
L 1
h
L 1
h
L
2

(
h

1
)
2
1

L 1
h 1
T ( n )  h 2i  ( h  1 )2h  1 
i 0
h( 2h  1 )  ( h  1 )2h  1  ( 2h  1 )  h
Then T ( n )  n  h  O( n )
 Hence, using Heapify requires only O(n) operations instead of
O (n logn).
Prof. Amr Goneid, AUC
40
Explore
 How to use Heapify in removing highest priority
 How to make a heap act as a stack
 How to make a heap act as a queue
Prof. Amr Goneid, AUC
41