A Priority Queue is a specialized data structure that retains elements in a way that prioritizes certain elements over others. Unlike standard queues that follow a first-in, first-out (FIFO) principle, priority queues allow for retrieval that is based on the priority of the elements.
In typical implementations, each element has a priority associated with it, and elements with higher priorities are dequeued before those with lower priorities. If two elements have the same priority, they are processed according to their order in the queue.
Priority queues have a wide range of applications, including:
Java provides a built-in implementation of a priority queue through the PriorityQueue class in the java.util
package. Below are the basic steps to implement and work with PriorityQueue.
To use PriorityQueue
, start by importing the package:
import java.util.PriorityQueue;
You can create a simple priority queue using the default natural ordering of its elements or by providing a custom comparator.
Here's how you can create a priority queue with default natural ordering using integers:
PriorityQueue<Integer> pq = new PriorityQueue<>(); pq.add(10); pq.add(5); pq.add(20); pq.add(15); // The element with the highest priority (smallest integer) will be at the head of the queue System.out.println("Priority Queue: " + pq);
Priority Queue: [5, 10, 20, 15]
In this example, the integer with the smallest value has the highest priority.
To retrieve and remove the head of the queue (the highest priority element), use the poll()
method:
int head = pq.poll(); System.out.println("Head of queue: " + head); System.out.println("Updated Priority Queue: " + pq);
Head of queue: 5
Updated Priority Queue: [10, 15, 20]
Sometimes, you might need elements ordered based on custom criteria. This can be achieved using a Comparator
. Below is an example of setting up a priority queue that prioritizes strings by their length:
PriorityQueue<String> stringPQ = new PriorityQueue<>((s1, s2) -> Integer.compare(s1.length(), s2.length())); // Adding elements stringPQ.add("apple"); stringPQ.add("pear"); stringPQ.add("banana"); stringPQ.add("kiwi"); // Retrieving elements based on length while (!stringPQ.isEmpty()) { System.out.println(stringPQ.poll()); }
kiwi
pear
apple
banana
In this example, strings are dequeued based on their length, demonstrating a custom ordering mechanism.
The PriorityQueue
class offers various methods that help in managing your queue:
Example:
System.out.println("Is the queue empty? " + pq.isEmpty()); System.out.println("Size of the queue: " + pq.size());
The PriorityQueue
in Java is backed by a binary heap, which provides efficient methods for inserting and removing elements:
This makes it quite suitable for scenarios where you need to perform a lot of insertions and deletions while maintaining the order of processing.
Imagine a scenario where you need to manage job priorities in an operating system. Here's a skeleton implementation that uses PriorityQueue
:
class Job implements Comparable<Job> { int id; int priority; Job(int id, int priority) { this.id = id; this.priority = priority; } @Override public int compareTo(Job other) { // Higher priority first return Integer.compare(other.priority, this.priority); } } public class JobScheduler { public static void main(String[] args) { PriorityQueue<Job> jobQueue = new PriorityQueue<>(); jobQueue.add(new Job(1, 3)); jobQueue.add(new Job(2, 1)); jobQueue.add(new Job(3, 2)); while (!jobQueue.isEmpty()) { Job job = jobQueue.poll(); System.out.println("Processing job ID: " + job.id + " with priority: " + job.priority); } } }
Processing job ID: 1 with priority: 3
Processing job ID: 3 with priority: 2
Processing job ID: 2 with priority: 1
This simulation shows how job IDs are processed based on priority, demonstrating the practical application of a priority queue in a scheduling system.
16/11/2024 | DSA
23/09/2024 | DSA
15/11/2024 | DSA
13/10/2024 | DSA
08/12/2024 | DSA
08/12/2024 | DSA
03/09/2024 | DSA
16/11/2024 | DSA
15/11/2024 | DSA
06/12/2024 | DSA
15/11/2024 | DSA
16/11/2024 | DSA