Priority Queue Implementation in Rust

1. Introduction

A priority queue is a specialized queue data structure that operates based on priorities assigned to its items. In a priority queue, an element with a higher priority is dequeued before an element with a lower priority. If two elements have the same priority, then they are served based on their order in the queue.

2. Implementation Steps

1. Use Rust's standard BinaryHeap structure for the internal representation of the priority queue.

2. Define the PriorityQueue struct with a BinaryHeap to store the queue elements and their priorities.

3. Implement a new function to initialize the priority queue.

4. Implement an enqueue function to add an element with a given priority.

5. Implement a dequeue function to remove the element with the highest priority.

6. Implement a peek function to view the highest priority element without removing it.

7. Implement an is_empty function to check if the priority queue is empty.

3. Implementation in Rust Programming

use std::collections::BinaryHeap;
use std::cmp::Reverse;
// Defining the PriorityQueue struct
pub struct PriorityQueue<T> {
    elements: BinaryHeap<Reverse<(i32, T)>>,
}
impl<T> PriorityQueue<T> {
    // Initialize an empty priority queue
    pub fn new() -> Self {
        PriorityQueue {
            elements: BinaryHeap::new(),
        }
    }
    // Add an element with a given priority to the queue
    pub fn enqueue(&mut self, priority: i32, value: T) {
        self.elements.push(Reverse((priority, value)));
    }
    // Remove and return the element with the highest priority
    pub fn dequeue(&mut self) -> Option<T> {
        self.elements.pop().map(|x| x.0 .1)
    }
    // View the highest priority element without removing it
    pub fn peek(&self) -> Option<&T> {
        self.elements.peek().map(|x| &x.0 .1)
    }
    // Check if the priority queue is empty
    pub fn is_empty(&self) -> bool {
        self.elements.is_empty()
    }
}
fn main() {
    let mut pq = PriorityQueue::new();
    pq.enqueue(3, "Low");
    pq.enqueue(1, "Very Low");
    pq.enqueue(5, "High");
    pq.enqueue(4, "Medium");
    println!("Peek into the PriorityQueue: {:?}", pq.peek());
    println!("Dequeue from PriorityQueue: {:?}", pq.dequeue());
    println!("Peek into the PriorityQueue after dequeue: {:?}", pq.peek());
}

Output:

Peek into the PriorityQueue: Some("High")
Dequeue from PriorityQueue: Some("High")
Peek into the PriorityQueue after dequeue: Some("Medium")

Explanation:

1. Rust's BinaryHeap is a max-heap, meaning the largest element is at the top. To use it for a priority queue, we need to reverse the order. The Reverse wrapper provides this reversed order.

2. The PriorityQueue struct is defined to hold elements along with their priorities. It internally uses BinaryHeap to automatically manage the order based on priority.

3. The new function initializes an empty priority queue.

4. The enqueue function allows adding an element to the queue along with a specified priority.

5. The dequeue function removes and returns the highest priority element from the queue.

6. The peek function provides a view of the highest priority element without dequeuing it.

7. The is_empty function is used to check if the priority queue has any elements left.

8. The main function demonstrates the priority queue's usage by enqueuing various elements and then peeking and dequeuing them.


Comments