Open In App

Introduction to Priority Queue

Last Updated : 18 Oct, 2025
Comments
Improve
Suggest changes
270 Likes
Like
Report

A priority queue is a type of queue where each element is associated with a priority value, and elements are served based on their priority rather than their insertion order.

  • Elements with higher priority are retrieved or removed before those with lower priority.
  • When a new item is added, it is inserted according to its priority.

The binary heap is the most common implementation of a priority queue:

  • A min-heap allows quick access to the element with the smallest value.
  • A max-heap allows quick access to the element with the largest value.
  • Binary heaps are complete binary trees, making them easy to implement using arrays.
  • Using arrays provides cache-friendly memory access, improving performance.

Priority queues are widely used in algorithms such as Dijkstra’s shortest path algorithm, Prim’s minimum spanning tree algorithm, and Huffman coding for data compression.

Types of Priority Queue

file
  • Min-Heap: In this queue, elements with lower values have higher priority. For example, with elements 4, 6, 8, 9, and 10, 4 will be dequeued first since it has the smallest value, and the dequeue operation will return 4.
  • Max-Heap: Elements with higher values have higher priority. The root of the heap is the highest element, and it is dequeued first. The queue adjusts by maintaining the heap property after each insertion or deletion.

Array Representation of Binary Heap:

Since the heap is maintained in the form of a complete binary tree, so it can be represented in the form of an array. To keep the tree complete and shallow, while inserting a new element insert it in the leftmost vacant position in the last level i.e., at the end of our array. Similarly, while extracting maximum replace the root with the last leaf at the last level i.e., the last element of the array.

6-

Implementation of Priority Queue Using Heap :

A Binary Heap is ideal for priority queue implementation as it offers better performance The largest key is at the top and can be removed in O(log n) time, with the heap property restored efficiently. If a new entry is inserted immediately, its O(log n) insertion time may overlap with restoration. Since heaps use contiguous storage, they efficiently handle large datasets while ensuring logarithmic time for insertions and deletions.

  • insert(p): Inserts a new element with priority p.
  • pop(): Extracts an element with maximum priority.
  • getMax(): Returns an element with maximum priority.
C++
#include <iostream>
#include <vector>
using namespace std;

// Returns index of parent
int parent(int i) { return (i - 1) / 2; }

// Returns index of left child
int leftChild(int i) { return 2 * i + 1; }

// Returns index of right child
int rightChild(int i) { return 2 * i + 2; }

// Shift up to maintain max-heap property
void shiftUp(int i, vector<int> &arr) {
    while (i > 0 && arr[parent(i)] < arr[i]) {
        swap(arr[parent(i)], arr[i]);
        i = parent(i);
    }
}

// Shift down to maintain max-heap property
void shiftDown(int i, vector<int> &arr, int size) {
    int maxIndex = i;
    int l = leftChild(i);
    if (l < size && arr[l] > arr[maxIndex]) maxIndex = l;
    int r = rightChild(i);
    if (r < size && arr[r] > arr[maxIndex]) maxIndex = r;

    if (i != maxIndex) {
        swap(arr[i], arr[maxIndex]);
        shiftDown(maxIndex, arr, size);
    }
}

// Insert a new element
void insert(int p, vector<int> &arr) {
    arr.push_back(p);
    shiftUp(arr.size() - 1, arr);
}

// Extract element with maximum priority
int pop(vector<int> &arr) {
    int size = arr.size();
    if (size == 0) return -1;
    int result = arr[0];
    arr[0] = arr[size - 1];
    arr.pop_back();
    shiftDown(0, arr, arr.size());
    return result;
}

// Get current maximum element
int getMax(vector<int> &arr) {
    if (arr.empty()) return -1;
    return arr[0];
}

// Print heap
void printHeap(vector<int> &arr) {
    for (int x : arr) cout << x << " ";
    cout << endl;
}

int main() {
    vector<int> pq;

    insert(45, pq);
    insert(20, pq);
    insert(14, pq);
    insert(12, pq);
    insert(31, pq);
    insert(7, pq);
    insert(11, pq);
    insert(13, pq);
    insert(7, pq);

    cout << "Priority Queue after inserts: ";
    printHeap(pq);

    // Demonstrate getMax
    cout << "Current max element: " << getMax(pq) << endl;

    // Demonstrate extractMax
    pop(pq) ;
    cout << "Priority Queue after extracting max: ";
    printHeap(pq);


    return 0;
}
Java
import java.util.ArrayList;
import java.util.Collections;

 class GFG {

    // Returns index of parent
    static int parent(int i) { return (i - 1) / 2; }

    // Returns index of left child
    static int leftChild(int i) { return 2 * i + 1; }

    // Returns index of right child
    static int rightChild(int i) { return 2 * i + 2; }

    // Shift up to maintain max-heap property
    static void shiftUp(int i, ArrayList<Integer> arr) {
        while (i > 0 && arr.get(parent(i)) < arr.get(i)) {
            Collections.swap(arr, parent(i), i);
            i = parent(i);
        }
    }

    // Shift down to maintain max-heap property
    static void shiftDown(int i, ArrayList<Integer> arr, int size) {
        int maxIndex = i;
        int l = leftChild(i);
        if (l < size && arr.get(l) > arr.get(maxIndex)) maxIndex = l;
        int r = rightChild(i);
        if (r < size && arr.get(r) > arr.get(maxIndex)) maxIndex = r;

        if (i != maxIndex) {
            Collections.swap(arr, i, maxIndex);
            shiftDown(maxIndex, arr, size);
        }
    }

    // Insert a new element
    static void insert(int p, ArrayList<Integer> arr) {
        arr.add(p);
        shiftUp(arr.size() - 1, arr);
    }

    // Extract element with maximum priority
    static int pop(ArrayList<Integer> arr) {
        int size = arr.size();
        if (size == 0) return -1;
        int result = arr.get(0);
        arr.set(0, arr.get(size - 1));
        arr.remove(size - 1);
        shiftDown(0, arr, arr.size());
        return result;
    }

    // Get current maximum element
    static int getMax(ArrayList<Integer> arr) {
        if (arr.isEmpty()) return -1;
        return arr.get(0);
    }

    // Print heap
    static void printHeap(ArrayList<Integer> arr) {
        for (int x : arr) System.out.print(x + " ");
        System.out.println();
    }

    public static void main(String[] args) {
        ArrayList<Integer> pq = new ArrayList<>();


        insert(45, pq);
        insert(20, pq);
        insert(14, pq);
        insert(12, pq);
        insert(31, pq);
        insert(7, pq);
        insert(11, pq);
        insert(13, pq);
        insert(7, pq);

        System.out.print("Priority Queue after inserts: ");
        printHeap(pq);

        // Demonstrate getMax
        System.out.println("Current max element: " + getMax(pq));

        // Demonstrate extractMax
        pop(pq);
        System.out.print("Priority Queue after extracting max: ");
        printHeap(pq);

    }
}
Python
# Returns index of parent
def parent(i):
    return (i - 1) // 2

# Returns index of left child
def leftChild(i):
    return 2 * i + 1

# Returns index of right child
def rightChild(i):
    return 2 * i + 2

# Shift up to maintain max-heap property
def shiftUp(i, arr):
    while i > 0 and arr[parent(i)] < arr[i]:
        arr[parent(i)], arr[i] = arr[i], arr[parent(i)]
        i = parent(i)

# Shift down to maintain max-heap property
def shiftDown(i, arr, size):
    maxIndex = i
    l = leftChild(i)
    if l < size and arr[l] > arr[maxIndex]:
        maxIndex = l
    r = rightChild(i)
    if r < size and arr[r] > arr[maxIndex]:
        maxIndex = r

    if i != maxIndex:
        arr[i], arr[maxIndex] = arr[maxIndex], arr[i]
        shiftDown(maxIndex, arr, size)

# Insert a new element
def insert(p, arr):
    arr.append(p)
    shiftUp(len(arr) - 1, arr)

# Extract element with maximum priority
def pop(arr):
    size = len(arr)
    if size == 0:
        return -1
    result = arr[0]
    arr[0] = arr[size - 1]
    arr.pop()
    shiftDown(0, arr, len(arr))
    return result

# Get current maximum element
def getMax(arr):
    if not arr:
        return -1
    return arr[0]


# Print heap
def printHeap(arr):
    print(" ".join(map(str, arr)))

# Driver code
if __name__ == "__main__":
    pq = []

    insert(45, pq)
    insert(20, pq)
    insert(14, pq)
    insert(12, pq)
    insert(31, pq)
    insert(7, pq)
    insert(11, pq)
    insert(13, pq)
    insert(7, pq)

    print("Priority Queue after inserts: ", end="")
    printHeap(pq)

    # Demonstrate getMax
    print("Current max element:", getMax(pq))

    # Demonstrate extractMax
    pop(pq)
    print("Priority Queue after extracting max: ", end="")
    printHeap(pq)
C#
using System;
using System.Collections.Generic;

class GFG
{
    // Returns index of parent
    static int parent(int i) => (i - 1) / 2;

    // Returns index of left child
    static int leftChild(int i) => 2 * i + 1;

    // Returns index of right child
    static int rightChild(int i) => 2 * i + 2;

    // Shift up to maintain max-heap property
    static void shiftUp(int i, List<int> arr)
    {
        while (i > 0 && arr[parent(i)] < arr[i])
        {
            int temp = arr[parent(i)];
            arr[parent(i)] = arr[i];
            arr[i] = temp;
            i = parent(i);
        }
    }

    // Shift down to maintain max-heap property
    static void shiftDown(int i, List<int> arr, int size)
    {
        int maxIndex = i;
        int l = leftChild(i);
        if (l < size && arr[l] > arr[maxIndex]) maxIndex = l;
        int r = rightChild(i);
        if (r < size && arr[r] > arr[maxIndex]) maxIndex = r;

        if (i != maxIndex)
        {
            int temp = arr[i];
            arr[i] = arr[maxIndex];
            arr[maxIndex] = temp;
            shiftDown(maxIndex, arr, size);
        }
    }

    // Insert a new element
    static void insert(int p, List<int> arr)
    {
        arr.Add(p);
        shiftUp(arr.Count - 1, arr);
    }

    // Extract element with maximum priority
    static int pop(List<int> arr)
    {
        int size = arr.Count;
        if (size == 0) return -1;
        int result = arr[0];
        arr[0] = arr[size - 1];
        arr.RemoveAt(size - 1);
        shiftDown(0, arr, arr.Count);
        return result;
    }

    // Get current maximum element
    static int getMax(List<int> arr)
    {
        if (arr.Count == 0) return -1;
        return arr[0];
    }

 
    // Print heap
    static void printHeap(List<int> arr)
    {
        foreach (int x in arr)
        {
            Console.Write(x + " ");
        }
        Console.WriteLine();
    }

    static void Main(string[] args)
    {
        List<int> pq = new List<int>();

        insert(45, pq);
        insert(20, pq);
        insert(14, pq);
        insert(12, pq);
        insert(31, pq);
        insert(7, pq);
        insert(11, pq);
        insert(13, pq);
        insert(7, pq);

        Console.Write("Priority Queue after inserts: ");
        printHeap(pq);

        // Demonstrate getMax
        Console.WriteLine("Current max element: " + getMax(pq));

        // Demonstrate extractMax
        pop(pq);
        Console.Write("Priority Queue after extracting max: ");
        printHeap(pq);

       
    }
}
JavaScript
// Returns index of parent
function parent(i) { return Math.floor((i - 1) / 2); }

// Returns index of left child
function leftChild(i) { return 2 * i + 1; }

// Returns index of right child
function rightChild(i) { return 2 * i + 2; }

// Shift up to maintain max-heap property
function shiftUp(i, arr) {
    while (i > 0 && arr[parent(i)] < arr[i]) {
        [arr[parent(i)], arr[i]] = [arr[i], arr[parent(i)]];
        i = parent(i);
    }
}

// Shift down to maintain max-heap property
function shiftDown(i, arr, size) {
    let maxIndex = i;
    const l = leftChild(i);
    if (l < size && arr[l] > arr[maxIndex]) maxIndex = l;
    const r = rightChild(i);
    if (r < size && arr[r] > arr[maxIndex]) maxIndex = r;

    if (i !== maxIndex) {
        [arr[i], arr[maxIndex]] = [arr[maxIndex], arr[i]];
        shiftDown(maxIndex, arr, size);
    }
}

// Insert a new element
function insert(p, arr) {
    arr.push(p);
    shiftUp(arr.length - 1, arr);
}

// Extract element with maximum priority
function pop(arr) {
    const size = arr.length;
    if (size === 0) return -1;
    const result = arr[0];
    arr[0] = arr[size - 1];
    arr.pop();
    shiftDown(0, arr, arr.length);
    return result;
}

// Get current maximum element
function getMax(arr) {
    if (arr.length === 0) return -1;
    return arr[0];
}



// Print heap
function printHeap(arr) {
    console.log(arr.join(" "));
}

// Driver code
const pq = [];

insert(45, pq);
insert(20, pq);
insert(14, pq);
insert(12, pq);
insert(31, pq);
insert(7, pq);
insert(11, pq);
insert(13, pq);
insert(7, pq);

console.log("Priority Queue after inserts: ");
printHeap(pq);

// Demonstrate getMax
console.log("Current max element:", getMax(pq));

// Demonstrate extractMax
pop(pq);
console.log("Priority Queue after extracting max: ");
printHeap(pq);

Output
Priority Queue after inserts: 45 31 14 13 20 7 11 12 7 
Current max element: 45
Priority Queue after extracting max: 31 20 14 13 7 7 11 12 

Time Complexity: O(log n), for all the operation, except getMax(), which has time complexity of O(1).
Space Complexity: O(n)

Difference between Priority Queue and Queue

There is no priority attached to elements in a queue, the rule of first-in-first-out(FIFO) is implemented whereas, in a priority queue, the elements have a priority. The elements with higher priority are served first.

Library Implementation of Priority Queue

3

Operations on a Priority Queue

A typical priority queue supports the following operations:

1) Insertion (push) : When a new item is inserted in a Max-Heap, if it has the highest value, it becomes the root; in a Min-Heap, if it has the smallest value, it becomes the root. Otherwise, it is placed so that all higher-priority elements (larger in Max-Heap, smaller in Min-Heap) are accessed before it.

2) Deletion(pop) : We usually remove the highest-priority item, which is always at the top. After removing it, the next highest-priority item automatically takes its place at the top.

3) top : This operation only returns the highest priority item (which is typically available at the top) and does not make any change to the priority queue.

C++
#include <iostream>
#include <queue>
#include <vector>
using namespace std;

int main() {
    
    // Create a max priority queue 
    priority_queue<int> pq;

    // Insert elements into the priority queue
    pq.push(10);
    pq.push(30);
  
    cout << "Priority Queue elements (max-heap):\n";

    // Access elements and pop them one by one
    while (!pq.empty()) {
        
        // Access the top (highest priority element)
        cout << "Top element: " << pq.top() << endl;

        // Remove the top element
        pq.pop();

        // Print remaining size
        cout << "Remaining size: " << pq.size() << "\n\n";
    }

    // Check if empty
    if (pq.empty()) {
        cout << "Priority Queue is now empty.\n";
    }

    return 0;
}
Java
import java.util.PriorityQueue;
import java.util.Collections;
 class GFG {
    public static void main(String[] args) {

        // Create a max priority queue 
        PriorityQueue<Integer> pq = new PriorityQueue<>(Collections.reverseOrder());

        // Insert elements into the priority queue
        pq.add(10);
        pq.add(30);

        System.out.println("Priority Queue elements (max-heap):");

        // Access elements and pop them one by one
        while (!pq.isEmpty()) {

            // Access the top (highest priority element)
            System.out.println("Top element: " + pq.peek());

            // Remove the top element
            pq.poll();

            // Print remaining size
            System.out.println("Remaining size: " + pq.size() + "\n");
        }

        // Check if empty
        if (pq.isEmpty()) {
            System.out.println("Priority Queue is now empty.");
        }
    }
}
Python
import heapq

if __name__ == "__main__":
     # Create a max priority queue using min heap with negative values
    pq = []

    # Insert elements into the priority queue
    heapq.heappush(pq, -10)
    heapq.heappush(pq, -30)

    print("Priority Queue elements (max-heap):")

    # Access elements and pop them one by one
    while pq:

        # Access the top (highest priority element)
        print("Top element:", -pq[0])

        # Remove the top element
        heapq.heappop(pq)

        # Print remaining size
        print("Remaining size:", len(pq), "\n")

    # Check if empty
    if not pq:
        print("Priority Queue is now empty.")
C#
using System;
using System.Collections.Generic;

class GFG {
    static void Main() {

        // Create a max priority queue 
        SortedSet<int> pq = new SortedSet<int>(Comparer<int>.Create((a, b) => b.CompareTo(a)));

        // Insert elements into the priority queue
        pq.Add(10);
        pq.Add(30);

        Console.WriteLine("Priority Queue elements (max-heap):");

        // Access elements and pop them one by one
        while (pq.Count > 0) {

            // Access the top (highest priority element)
            int top = pq.Min;
            Console.WriteLine("Top element: " + top);

            // Remove the top element
            pq.Remove(top);

            // Print remaining size
            Console.WriteLine("Remaining size: " + pq.Count + "\n");
        }

        // Check if empty
        if (pq.Count == 0) {
            Console.WriteLine("Priority Queue is now empty.");
        }
    }
}
JavaScript
class MaxPriorityQueue {
    constructor() {
        this.data = [];
    }

    push(val) {
        this.data.push(val);
        this.data.sort((a, b) => b - a);
    }

    top() {
        return this.data[0];
    }

    pop() {
        this.data.shift();
    }

    size() {
        return this.data.length;
    }

    empty() {
        return this.data.length === 0;
    }
}
//Driver Code
    // Create a max priority queue 
    const pq = new MaxPriorityQueue();

    // Insert elements into the priority queue
    pq.push(10);
    pq.push(30);

    console.log("Priority Queue elements (max-heap):");

    // Access elements and pop them one by one
    while (!pq.empty()) {

        // Access the top (highest priority element)
        console.log("Top element:", pq.top());

        // Remove the top element
        pq.pop();

        // Print remaining size
        console.log("Remaining size:", pq.size(), "\n");
    }

    // Check if empty
    if (pq.empty()) {
        console.log("Priority Queue is now empty.");
    }

Output
Priority Queue elements (max-heap):
Top element: 30
Remaining size: 1

Top element: 10
Remaining size: 0

Priority Queue is now empty.

Applications of Priority Queue 


Article Tags :

Explore