Implementing a Queue in Rust using a Vector

Implementing a Queue in Rust using a Vector

Queues are fundamental data structures in computer science, often used for managing data in a first-in, first-out (FIFO) manner.

Before diving into the implementation details, let's briefly discuss what queues are and how they work.

  • Queue

    A queue is a collection of elements that supports two primary operations: enqueue and dequeue.

  • Enqueue method

    Enqueue adds an element to the back of the queue,

  • Dequeue method

    Dequeue removes and returns the front element of the queue.

Additionally, queues typically support operations like peek (to view the front element without removing it) and empty (to check if the queue is empty).

let's start by defining our structs

struct MyQueue {
    queue: Vec<i32>,
}

Structs in rust are similar to interfaces in typescript.

impl is used to define implementation on our struct type MyQueue

impl MyQueue {
    // Constructor for creating a new empty queue
    fn new() -> Self {
        MyQueue { queue: Vec::new() }
    }
}

new(): This method serves as the constructor for the MyQueue struct. It initializes an empty vector to store the elements of the queue.

push(x): This method takes an element x as input and adds it to the back of the queue by using the push method of the vector.

impl MyQueue {
    fn new() -> Self {
        MyQueue { queue: Vec::new() }  
    }
    fn push(&mut self, x: i32) {
        self.queue.push(x)
    }    
}

Example useable

let obj = MyQueue::new();
obj.push(x);

We can use the other vec method to implement dequeue, peek and other methods

here is the full code

struct MyQueue {
    queue: Vec<i32>,
}

impl MyQueue {
    // Constructor for creating a new empty queue
    fn new() -> Self {
        MyQueue { queue: Vec::new() }
    }

    // Method to add an element to the back of the queue
    fn push(&mut self, x: i32) {
        self.queue.push(x)
    }

    // Method to remove and return the front element of the queue
    fn pop(&mut self) -> i32 {
        self.queue.remove(0)
    }

    // Method to view the front element of the queue without removing it
    fn peek(&self) -> i32 {
        self.queue.first().unwrap().to_owned()
    }

    // Method to check if the queue is empty
    fn empty(&self) -> bool {
        self.queue.is_empty()
    }
}

Similarly, we can create a generic version of the queue as well.

struct MyQueue<T> {
    queue: Vec<T>,
}

impl<T> MyQueue<T> {
    fn new() -> Self {
        MyQueue { queue: Vec::new() }
    }

    fn push(&mut self, x: T) {
        self.queue.push(x)
    }

    fn pop(&mut self) -> Option<T> {
        self.queue.remove(0)
    }

    fn peek(&self) -> Option<&T> {
        self.queue.first()
    }

    fn empty(&self) -> bool {
        self.queue.is_empty()
    }
}

Note: that peek and pop method return Option type

Did you find this article valuable?

Support Pratik Sharma by becoming a sponsor. Any amount is appreciated!