Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve Queue Implementation #791

Merged
merged 1 commit into from
Sep 22, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 38 additions & 45 deletions src/data_structures/queue.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
//! This module provides a generic `Queue` data structure, implemented using
//! Rust's `LinkedList` from the standard library. The queue follows the FIFO
//! (First-In-First-Out) principle, where elements are added to the back of
//! the queue and removed from the front.

use std::collections::LinkedList;

#[derive(Debug)]
Expand All @@ -6,33 +11,50 @@ pub struct Queue<T> {
}

impl<T> Queue<T> {
// Creates a new empty Queue
pub fn new() -> Queue<T> {
Queue {
elements: LinkedList::new(),
}
}

// Adds an element to the back of the queue
pub fn enqueue(&mut self, value: T) {
self.elements.push_back(value)
}

// Removes and returns the front element from the queue, or None if empty
pub fn dequeue(&mut self) -> Option<T> {
self.elements.pop_front()
}

// Returns a reference to the front element of the queue, or None if empty
pub fn peek_front(&self) -> Option<&T> {
self.elements.front()
}

// Returns a reference to the back element of the queue, or None if empty
pub fn peek_back(&self) -> Option<&T> {
self.elements.back()
}

// Returns the number of elements in the queue
pub fn len(&self) -> usize {
self.elements.len()
}

// Checks if the queue is empty
pub fn is_empty(&self) -> bool {
self.elements.is_empty()
}

// Clears all elements from the queue
pub fn drain(&mut self) {
self.elements.clear();
}
}

// Implementing the Default trait for Queue
impl<T> Default for Queue<T> {
fn default() -> Queue<T> {
Queue::new()
Expand All @@ -44,55 +66,26 @@ mod tests {
use super::Queue;

#[test]
fn test_enqueue() {
let mut queue: Queue<u8> = Queue::new();
queue.enqueue(64);
assert!(!queue.is_empty(), "Queue should not be empty after enqueue");
}

#[test]
fn test_dequeue() {
let mut queue: Queue<u8> = Queue::new();
queue.enqueue(32);
queue.enqueue(64);
let retrieved_dequeue = queue.dequeue();
assert_eq!(
retrieved_dequeue,
Some(32),
"Dequeue should return the first element"
);
}
fn test_queue_functionality() {
let mut queue: Queue<usize> = Queue::default();

#[test]
fn test_peek_front() {
let mut queue: Queue<u8> = Queue::new();
assert!(queue.is_empty());
queue.enqueue(8);
queue.enqueue(16);
let retrieved_peek = queue.peek_front();
assert_eq!(
retrieved_peek,
Some(&8),
"Peek should return a reference to the first element"
);
}
assert!(!queue.is_empty());
assert_eq!(queue.len(), 2);

#[test]
fn test_size() {
let mut queue: Queue<u8> = Queue::new();
queue.enqueue(8);
queue.enqueue(16);
assert_eq!(
2,
queue.len(),
"Queue length should be equal to the number of enqueued elements"
);
}
assert_eq!(queue.peek_front(), Some(&8));
assert_eq!(queue.peek_back(), Some(&16));

#[test]
fn test_is_empty() {
let mut queue: Queue<u8> = Queue::new();
assert!(queue.is_empty(), "Newly created queue should be empty");
queue.enqueue(8);
assert!(!queue.is_empty(), "Queue should not be empty after enqueue");
assert_eq!(queue.dequeue(), Some(8));
assert_eq!(queue.len(), 1);
assert_eq!(queue.peek_front(), Some(&16));
assert_eq!(queue.peek_back(), Some(&16));

queue.drain();
assert!(queue.is_empty());
assert_eq!(queue.len(), 0);
assert_eq!(queue.dequeue(), None);
}
}