0% found this document useful (0 votes)
19 views

Priority Queue Notes

Uploaded by

RaJu Bhai
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
19 views

Priority Queue Notes

Uploaded by

RaJu Bhai
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 18

Priority Queues

Introduction
● Priority Queues are abstract data structures where each data/value in the
queue has a certain priority.
● A priority queue is a special type of queue in which each element is served
according to its priority.
● If elements with the same priority occur, they are served according to their
order in the queue.
● Generally, the value of the element itself is considered for assigning the
priority.
● For example​, the element with the highest value is considered as the highest
priority element. However, in some cases, we may assume the element with
the lowest value to be the highest priority element. In other cases, we can set
priorities according to our needs.

Difference between Priority Queue and Normal Queue


In a queue, the F
​ irst-In-First-Out(FIFO) ​rule is implemented whereas, in a priority
queue, the values are removed based on priority. The element with the highest
priority is removed first.

Main Priority Queues Operations


● Insert (key, data)​: Inserts data with a key to the priority queue. Elements are
ordered based on key.
● DeleteMin/DeleteMax​: Remove and return the element with the
smallest/largest key.
● GetMinimum/GetMaximum​: Return the element with the smallest/largest
key without deleting it.

1
Auxiliary Priority Queues Operations
● kth - Smallest/kth – Largest​: Returns the kth -Smallest/kth –Largest key in
the priority queue.
● Size​: Returns the number of elements in the priority queue.
● Heap Sort​: Sorts the elements in the priority queue based on priority (key).

Priority Queue Applications


Priority queues have many applications - a few of them are listed below:
● Data compression:​ Huffman Coding algorithm
● Shortest path algorithms​: Dijkstra’s algorithm
● Minimum spanning tree algorithms​: Prim’s algorithm
● Event-driven simulation​: Customers in a line
● Selection problem:​ Finding the kth- smallest element

Priority Queue Implementations


Before discussing the actual implementation, let us enumerate the possible
options.

Unordered Array Implementation


● Elements are inserted into the array without bothering about the order.
Deletions (DeleteMax) are performed by searching the key and then deleting.
● Insertions complexity: O
​ (1)​.
● DeleteMin complexity: ​O(n)

Unordered List Implementation


● It is very similar to array implementation, but instead of using arrays, linked
lists are used.
● Insertions complexity: O
​ (1)​.
● DeleteMin complexity: ​O(n)​.
Ordered Array Implementation

2
● Elements are inserted into the array in sorted order based on the key field.
Deletions are performed at only one end.
● Insertions complexity: O
​ (n)​; DeleteMin complexity: O
​ (1)​.

Ordered List Implementation


● Elements are inserted into the list in sorted order based on the key field.
Deletions are performed at only one end, hence preserving the status of the
priority queue. All other functionalities associated with a linked list ADT are
performed without modification.
● Insertions complexity: O
​ (n)​; DeleteMin complexity: O
​ (1)​.

Binary Search Trees Implementation


● Both insertions and deletions take O
​ (log(n)) ​on average if insertions are
random (refer to Trees chapter).

Balanced Binary Search Trees Implementation


● Both insertions and deletion take​ O(log(n))​ in the worst case (refer to Trees
chapter).
Binary Heap Implementation
In subsequent sections, we will discuss this in full detail.

3
Heaps
● A heap is a tree with some special properties.
● The basic requirement of a heap is that the v
​ alue of a node must be ≥ (or ≤)
than the values of its children​. This is called the h
​ eap property​.
● A heap also has the additional property that all leaf nodes should be at ​h​ or
h – 1​ level (where h is the height of the tree) for some h > 0 (complete binary
trees).
● That means the heap should form a complete binary tree (as shown below).

In the examples below, the left tree is a heap (each element is greater than its
children) and the right tree is not a heap (since 11 is greater than 2).

4
Types of Heaps
Based on the property of a heap we can classify heaps into two types:
● Min heap:​ The value of a node must be less than or equal to the values of its
children.

● Max heap:​ The value of a node must be greater than or equal to the values
of its children.

5
Binary Heaps
● In a binary heap, each node may have up to two children.
● In practice, binary heaps are enough and we concentrate on binary min
heaps and binary max heaps for the remaining discussion.

Representing Heaps:​ Before looking at heap operations, let us see how heaps can
be represented. One possibility is using arrays. Since heaps are forming complete
binary trees, there will not be any wastage of locations. For the discussion below let
us assume that elements are stored in arrays, which starts at index 0. The previous
max heap can be represented as:

Heap Operations
Some of the important operations performed on a heap are described below along
with their algorithms.

Heapify
Heapify is the process of creating a heap data structure from a binary tree. It is
used to create a Min-Heap or a Max-Heap.

● Let the input array be

6
● Create a complete binary tree from the array

● Start from first index of the non-leaf node whose index is given by n
​ /2 - 1​.

● Set current element ​i​ as l​ argest​.


● The index of the left child is given by 2
​ i + 1​ and the right child is given by 2
​ i+
2​.
● If ​leftChild ​is greater than c
​ urrentElement​ (i.e. element at the ith index), set
leftChildIndex ​as largest. #
​ Condition1

● If ​rightChild​ is greater than element in ​largest​, set ​rightChildIndex​ as


largest​. #
​ Condition2

7
● Swap​ largest w
​ ith​ currentElement. ​#Condition3
● Repeat steps 3-7 until the subtrees are also heapified.
● For Min-Heap, both l​ eftChild ​and ​rightChild​ must be smaller than the
parent for all nodes.

Java Code
public class ​Priority_Queue ​{

private ArrayList<Integer> heap;

public ​Priority_Queue​() {
heap = new ArrayList<>();
}

boolean ​isEmpty​(){
return heap.size() == 0;
}

int ​size​(){
return heap.size();
}

int ​getMax​() throws PriorityQueueException{


if(isEmpty()){
// Throw an exception
throw new PriorityQueueException();
}
return heap.get(0);
}

public void ​heapify​(int i) {


int largest = i;
int l = ​2​ * i + ​1;​ ​//Index of Left Child
int r = ​2​ * i + ​2​; ​//Index of Right Child

​if​ (l < n ​&& ​arr[i] < arr[l]) ​#Condition1

8
largest = l;
​if​ (r < n ​&&​ arr[largest] < arr[r]) ​#Condition2
largest = r;

​if ​(largest!=i) {
int temp = heap.get(i);
heap.set(i, heap.get(largest));
heap.set(largest, temp);
heapify(largest);
}
}
}

Insert Element into Heap


Insertion into a heap can be done in two steps:
● Insert the new element at the end of the tree. #
​ Step1

● Move that element to its correct position in the heap.

9
Java Code
public void ​insert​(int element) {

heap.add(element);
int childIndex = heap.size()-1;
int parentIndex = (childIndex-1)/2;
while​(childIndex > 0) {
if​(heap.get(parentIndex) < heap.get(childIndex)) {
int temp = heap.get(parentIndex);
heap.set(parentIndex, heap.get(childIndex));
heap.set(childIndex, temp);
childIndex = parentIndex;
parentIndex = (childIndex - 1)/2;
}
else {
break;
}
}
}

Delete Max Element from Heap


There are three easy steps to remove max from the heap, we know that 0th
element would be the max.
● Set the 0th element with the last element.
● Remove the last element from the heap.
● Heapify the 0th element.
If you want to return the max element then store it before replacing it with the last
index, and return it in the end. Below shown is the java code for the same.

10
Java Code
public int ​removeMax​() throws PriorityQueueException {

if​(isEmpty()) {
throw new PriorityQueueException();
}
int retVal = heap.get(0);
heap.set(0, heap.get(heap.size()-1));
heap.remove(heap.size()-1);
if​(heap.size() > 1) {
heapify(0);
}
return ​retVal;
}

Implementation of Priority Queue


● Priority queue can be implemented using an array, a linked list, a heap data
structure, or a binary search tree.
● Among these data structures, heap data structure provides an efficient
implementation of priority queues.
● Hence, we will be using the heap data structure to implement the priority
queue in this tutorial.

Insertion and Deletion in a Priority Queue


The first step would be to represent the priority queue in the form of a
max/min-heap. Once it is heapified, the insertion and deletion operations can be
performed similar to that in a Heap. Refer to the codes discussed above for more
clarity.

11
Heap Sort
● Heap Sort is another example of an efficient sorting algorithm. Its main
advantage is that it has a great worst-case runtime of O
​ (nlog(n))​ regardless
of the input data.
● As the name suggests, Heap Sort relies heavily on the heap data structure - a
common implementation of a Priority Queue.
● Without a doubt, Heap Sort is one of the simplest sorting algorithms to
implement, and coupled with the fact that it's a fairly efficient algorithm
compared to other simple implementations, it's a common one to encounter.

Algorithm
● The heap-sort algorithm inserts all elements (from an unsorted array) into a
maxheap.
● Note that heap sort can be done i​ n-place​ with the array to be sorted.
● Since the tree satisfies the Max-Heap property, then the largest item is
stored at the root node.
● Swap​: Remove the root element and put at the end of the array (nth
position)
● Put the last item of the tree (heap) at the vacant place.
● Remove​: Reduce the size of the heap by 1.
● Heapify:​ Heapify the root element again so that we have the highest element
at root.
● The process is repeated until all the items in the list are sorted.
Consider the given illustrated example:
-> Applying heapsort to the unsorted array ​[12, 6, 10, 5, 1, 9]

12
13
14
Go through the given ​Java Code​ for better understanding:

public static void ​heapSort​(int input[], int startIndex, int endIndex) {

for​(int i=(input.length/2)-1; i>=0; i--) {


heapify(input, i, input.length);
}

int n = input.length;
for ​(int i=n-1; i>=0; i--) {
// Move current root to end
int temp = input[0];
input[0] = input[i];
input[i] = temp;

// call heapify on the reduced heap

15
heapify(input, 0, i);
}
}

public static void ​heapify​(int input[], int index, int arrLength) {


int largest = index;
int left = 2*index+1;
int right = 2*index+2;
​if​(left<arrLength && input[left]>input[largest])
largest = left;
}
​if​(right<arrLength && input[right]>input[largest]){
largest = right;
}

​if​(largest!=index){
int k = input[index];
input[index] = input[largest];
input[largest] = k;
heapify(input, largest, arrLength);
}
}

In-built Min-Heap in Java


A heap is created by using java’s inbuilt library named ​PriorityQueue​. This library
has the relevant functions to carry out various operations on a m
​ in-heap​ data
structure. Below is a list of these functions.

● add​– This function adds an element to the heap without altering the current
heap.
● remove​- This function returns the smallest data element from the heap.

Creating, inserting and removing from a Min-Heap


In the below example we supply a list of elements and the heapify function
rearranges the elements bringing the smallest element to the first position.

import java.util.PriorityQueue;

16
public class PriorityQueueUse {
public static void main(String[] args) {

PriorityQueue<Integer> pq = new PriorityQueue<>();


int arr[] = {9,1,0,4,7,3};
for(int i = 0; i < arr.length; i++){
pq.add(arr[i]);
}
for(int i = 0; i < arr.length; i++){
pq.remove();
}
}
}

When the above code is executed, it produces the following result −

[​0, 1​, ​3​, ​4​, ​7​, ​9​]

In-built Max-Heap in Python

For max heap you just need to change the initialisation with reverse order as shown
below:

PriorityQueue​<Integer> pq = new ​PriorityQueue​<>(Collections.reverseOrder());

K-Smallest Elements in a List


This is a good example of problem-solving via a heap data structure. The basic idea
here is to create a min-heap of all n elements and then extract the minimum
element K times (We know that the root element in a min-heap is the smallest
element).

17
Approach
● Build a min-heap of size ​n​ of all elements.
● Extract the minimum elements K
​ ​ times, i.e. delete the root and perform
heapify operation ​K​ times.
● Store all these K smallest elements.

Note: T
​ he code written using these insights can be found in the solution tab of the
problem itself.

18

You might also like