Professional Documents
Culture Documents
W5 PriorityQueue
W5 PriorityQueue
W5 PriorityQueue
INTRODUCTION TO ALGORITHMS
Department: Computer science
Course Code: CSS-215
Course Instructor: Asst. Prof. Dr. Mohammed
Ala’anzy
Office no.: G-405
Priority Queue
Collections. Insert and delete items.
deleteMin insert
Priority Queue
Priority Queue
A priority queue is abstract data-type which behaves similar to the linear queue except that each
element has priority.
The priority of elements in the priority queue will determine the order of removal of data-elements.
A priority queue only supports comparable elements.
Priority: 1 2 3 4 5 6
5 7 3 8 2 12
0 1 2 3 4 5
Front (Deletion) Rear (Insertion)
Priority Queue API (Operations)
Key must be Comparable
(bounded type parameter)
public class MaxPQ<Key extends Comparable<Key>>
MaxPQ() create an empty priority queue
MaxPQ(Key[] a) create a priority queue with given keys
void insert(Key v) insert a key into the priority queue
Key delMax() return and remove the largest key
boolean isEmpty() is the priority queue empty?
Key max() return the largest key
int size() number of entries in the priority queue
Priority Queue Operations
Insertion (Enqueue): This operation involves adding an element with its associated priority to the priority
queue. Elements are inserted in such a way that they are positioned according to their priorities. This operation
is crucial for building a priority queue.
Deletion (Dequeue): Dequeueing refers to removing the element with the highest (or lowest) priority from the
priority queue. The element that is dequeued is typically the one with the most significance in the context of the
application.
Peek (Get the highest priority element): The peek operation allows you to examine the element with the highest
priority without removing it from the priority queue. This is useful for inspecting the next item to be processed.
Size (Number of elements): You can inquire about the number of elements currently in the priority queue using
the size operation. It provides insight into the queue's current state.
IsEmpty (Check if empty): The isEmpty operation tells you whether the priority queue is empty or if it contains
one or more elements. This is useful for conditionally processing elements based on the queue's status.
Priority Queue Applications
Event-driven simulation [customers in a line, colliding particles]
Numerical computation [reducing roundoff error]
Data compression [Huffman codes]
Graph searching [Dijkstra's algorithm, Prim's algorithm]
Number theory [sum of powers]
Artificial intelligence [A* search]
Statistics [maintain largest M values in a sequence]
Operating systems [load balancing, interrupt handling]
Discrete optimization [bin packing, scheduling]
Spam filtering [Bayesian spam filter]
A Common Priority Queue
Implementation
Binary heaps are specialized binary trees that excel in managing priority queues.
They are structured in a way that ensures efficient access to the highest (or
lowest) priority element.
Heaps
Heap Applications
Three common applications:
Selection algorithms
Priority queues
Sorting
Introduction
A Heap is a binary tree which almost complete that is each level of the tree is
completely filled, except possibly the bottom level, and in this level, the nodes
are in the leftmost positions.
Also, it satisfies the heap-order property:
The data item stored in each node is greater (max-heap)/smaller(min-heap) than or equal to
the data items stored in its children. Thus the root is the biggest/smallest value.
In this lecture, the children must bigger than or equal to the parent.
Key Operations in a Binary Heap
Insertion: Adding elements to a binary heap while maintaining its properties. Insertion typically
takes O(log n) time, making it efficient.
Deletion (Extract Min/Max): Removing and returning the root element (min or max) while
reorganizing the heap to preserve its properties. Deletion also takes O(log n) time.
Peek (Get Min/Max): Retrieving the root element without removing it. Peek operates in O(1) time
since the root element is always readily available.
Applications of Binary Heaps
Dijkstra's Algorithm: Used to find the shortest path in graphs.
Heap Sort: An efficient sorting algorithm based on binary heaps.
Task Scheduling: Prioritizing tasks in operating systems and real-time systems.
Priority Queues: Used in various real-world scenarios where prioritization is crucial.
Applications of Binary Heaps
Use in many applications:
Operating system scheduler in multi-user environment
External sorting
Implementation of greedy algorithms
Discrete event simulation
21 16
19 68
24 31
21 16
19 68
24
65 26 32 31
Example: Insert 14
13
16
19 68
24 21
65 26 32 31
Example: Insert 14
13
This strategy known as percolate up.
14 16
19 68
24 21
65 26 32 31
Code Fragment
/**
* Insert into the priority queue, maintaining heap order.
* Duplicates are allowed.
* @param x the item to insert.
*/
public void insert( AnyType x )
{
if( currentSize == array.length-1)
enlargeArray( array.length * 2 + 1 );
// Percolate up
int hole =++currentSize;
for(; hole > 1 && x.compareTo(array[hole/2]) < 0;hole/=2)
array[hole]=array[ hole / 2 ];
Percolate Up
Percolate up, also known as bubble up or sift up, is an operation used in binary heaps to maintain the heap's ordering property after inserting
an element. It involves moving an element up the heap by repeatedly swapping it with its parent until the correct position is reached.
1. Start with the newly inserted element at the bottom of the heap.
2. Compare the element with its parent (if it has one). In a min-heap, if the element is smaller than its parent, or in a max-heap, if the
element is larger than its parent, you have a violation of the heap's ordering property.
3. If there is a violation, swap the element with its parent. This step ensures that the parent-child relationship satisfies the heap property.
4. Repeat steps 2 and 3 until either there is no violation (i.e., the element is in the correct position relative to its parent) or until the element
becomes the root of the heap.
The percolate up operation ensures that the newly inserted element "bubbles up" the heap to its correct position, maintaining the heap's
ordering property. This operation is crucial for maintaining the integrity of the binary heap, whether it's a min-heap or a max-heap.
Percolate up typically has a time complexity of O(log n), where n is the number of elements in the heap, because the element may
need to move up the height of the heap, which is logarithmic in the number of elements.
Example: Insert 14
13
21 16
19 68
24 31
65 26 32
Example: Insert 14
13
21 16
19 68
24 31
65 26 32 14
Example: Insert 14
13
21 16
19 68
24 14
65 26 32 31
Example: Insert 14
13
14 16
19 68
24 21
65 26 32 31
Percolate Up Pseudocode
Operation For A Min-heap:
void percolateUp(int[] heap, int index) {
while (index > 0) {
int parentIndex = (index - 1) / 2; // Calculate the parent's index
if (heap[index] < heap[parentIndex]) {
// Swap the element with its parent
int temp = heap[index];
heap[index] = heap[parentIndex];
heap[parentIndex] = temp;
14 16
19 68
19 21
65 26 32 31
Example: DeleteMin
Create a hole at the root
14 16
19 68
19 21
65 26 32 31
Example: DeleteMin
14
16
19 68
19 21
65 26 32 31
Example: DeleteMin
14
19 16
19 68
21
65 26 32 31
Example: DeleteMin
14
19 16
19 68
26 21
65 32 31
Example: DeleteMin
This strategy known as percolate 14
down – avoid swap routine.
19 16
19 68
26 21
65 31 32
Percolate Down
Percolate down, also known as sift down, is an operation used in binary heaps to maintain the heap's
ordering property after removing the root element or replacing it with a new element. The goal of
percolate down is to find the correct position for the element at the top of the heap (usually the root)
without performing unnecessary swaps.
The "avoid swap routine" version of percolate down aims to reduce the number of swaps, which can be
computationally expensive, especially if the heap is implemented in a memory-intensive environment.
Percolate Down
The percolate down operation without unnecessary swaps:
2. Compare the root element with its left and right children (if they exist).
3. Determine which child has the higher priority in a min-heap (lower value) or the lower priority in a max-heap (higher value).
4. If the root element is already in the correct position relative to its children, or if it doesn't have any children with higher priority, the heap
property is satisfied, and no swaps are needed. The element remains in its current position.
5. If there is a child with higher priority, instead of swapping the elements immediately, you update the root element with the value of the
higher-priority child. This effectively "sifts down" the element without swapping.
6. Repeat steps 2-5 with the new position of the element until the heap's ordering property is satisfied or until the element becomes a leaf node.
By following this "avoid swap routine," minimizing the number of swaps during the percolate down operation, which can lead to improved
performance, especially when dealing with large heaps.
The time complexity of percolate down without swaps is typically O(log n), where n is the number of elements in the heap.
Fragment Code For Percolate Down
/** Remove the smallest item from the priority queue.
*@return the smallest item, or throw UnderflowException, if empty.
*/
public AnyType deleteMin() {
if( isEmpty()) throw new UnderflowException( );
Any Type minItem = findMin();
array[1] = array[ currentSize-- ]; percolateDown ( 1 );
return minItem;
}
/**
* Internal method to percolate down in the heap.
* @param hole the index at which the percolate begins.
*/
private void percolateDown( int hole ){
int child;
Any Type tmp= array[ hole ];
for(; hole * 2 <= currentSize; hole = child){
child = hole * 2;
if( child != currentSize && array[ child + 1 ].compareTo( array[ child ] ) < 0 )
child++;
if( array[ child ].compareTo(tmp) < 0)
array[ hole ] = array[ child ];
else
break;
}
array[hole]= tmp;
}
Heap In Nutshell
1. Heap is a complete binary tree (BT).
2. Complete binary tree means all the levels should be full and on the left.
3. The full consider full if the items allocated from left side of the tree to the right.
5. To know the children of the the parent node we can apply the following formula:
1. When the starting of the array index = 1
6. To get the parent of a child; It can be found via the following formula:
Take the floor division of the number to get the parent index. When the
array start from 1.
10. In the max heap every parent is greater that its children 20
11. In the min heap every parent is less that its children
20 80 50 30 90 10 30 90 10
0 1 2 3 4 5
Heap In Nutshell
14. Step by step and level by level we change the tree by swapping to make it either min-heap or max-
heap, e.g., make the following array as a max-heap.
20
20 80 50 30 90 10
0 1 2 3 4 5
80 50
30 90 10
Heap In Nutshell
20
20 90 50 30 80 10
0 1 2 3 4 5
90 50
30 80 10
Heap In Nutshell
90
90 20 50 30 80 10
0 1 2 3 4 5
20 50
30 80 10
Heap In Nutshell
90
90 80 50 30 20 10
0 1 2 3 4 5
80 50
30 20 10
Heap In Nutshell
15. To do the swapping we need the heapify function.
/**
* Heapify function check every tree (to achieve the max heap
* @param The array; the size of array; the index for the position to check weather is it min heap or max-heap
*/
Heapify ( int arr[], int size, int index)
{ \\ to get the left child and the right child; When start the array from index 0;
int left=2*index+1;
int Right=2*i+2;
int max=index;
if (arr[left]>arr[max])
max=left;
if (arr[right]>arr[max])
max=right;
if (max !=index){ // means there is a violation in the property of heap (i.e. one of the previous conditions as achieved)
swap(arr[index],arr[max]);
}
}
// here we may have more items in the array (i.e., child of the right & left) then we should use Recursive
Heap In Nutshell
/**
* To ensure that the heapify has applied for all sub-trees in the heap
* The checking will starts from the last non-leaf node in the array
* @param The size of the array and the n of array
*/
heapbulid ( int arr[], int n) {
\\ The array stated from index 0; The heapify starts from the last parents’level Root@i=0
for ( int i=(n/2)-1; i>=0;i--)
heapifiy (arr,n,i);
}
Heap In Nutshell
/**
* Sorry function
* First we need to build the heap
*/
public void heapsort ( int arr[], int n) {
bulidheap (arr, n);
for ( int i=n-1; i>=0;i--){
swap(arr[0],arr[i]);
heapify(arr,i,0);
}
}
Heap In Nutshell
/**
* Main class
*
*/
public static void main ( string [] args) {
int arr[]={5,7,22,78,4,6}
int size=arr.length();
heapsort(arr,n);
print(arr);
}
Exercise
Develop binary heap based on the sequence below:
3, 4, 2, 9, 7, 8, 1
Based on the above binary heap tree, show the changes on the tree when you delete the minimum
value.
THANK YOU!