dsa/data_structures/queue.rs
1use crate::data_structures::node::Node;
2
3/// A queue data structure with a fixed capacity.
4///
5/// This structure implements a simple queue where elements of type `T` are
6/// enqueued and dequeued according to the First-In-First-Out (FIFO) principle.
7pub struct Queue<T> {
8 /// The front of the queue, represented by an `Option` of a `Box` containing the first `Node`.
9 ///
10 /// This points to the first element in the queue. If the queue is empty, this is `None`.
11 /// The front node is removed when dequeuing an element.
12 front: Option<Box<Node<T>>>,
13 /// A pointer to the rear node in the queue.
14 ///
15 /// This is a raw pointer to the last `Node` in the queue. It is used to quickly append new
16 /// nodes at the end when enqueuing. It is set to `null_mut` if the queue is empty.
17 rear: *mut Node<T>,
18 /// The current size of the queue.
19 ///
20 /// This keeps track of how many elements are in the queue. It is incremented when an element
21 /// is enqueued and decremented when an element is dequeued.
22 size: usize,
23}
24
25impl<T> Queue<T> {
26 /// Creates a new, empty `Queue`.
27 ///
28 /// # Examples
29 ///
30 /// ```
31 /// use dsa::data_structures::queue::Queue;
32 /// let queue: Queue<i32> = Queue::new();
33 /// assert!(queue.is_empty());
34 /// ```
35 pub fn new() -> Self {
36 Queue {
37 front: None,
38 rear: std::ptr::null_mut(),
39 size: 0,
40 }
41 }
42
43 /// Adds a value to the rear of the `Queue`.
44 ///
45 /// # Examples
46 ///
47 /// ```
48 /// use dsa::data_structures::queue::Queue;
49 /// let mut queue = Queue::new();
50 /// queue.enqueue(10);
51 /// queue.enqueue(20);
52 /// assert_eq!(queue.peek(), Some(&10));
53 /// ```
54 pub fn enqueue(&mut self, value: T) {
55 let new_node = Box::new(
56 Node::new(
57 value,
58 None
59 )
60 );
61
62 let new_node_ptr: *mut Node<T> = Box::into_raw(new_node);
63
64 if self.rear.is_null() {
65 self.front = unsafe {
66 Some(Box::from_raw(new_node_ptr))
67 };
68 self.rear = new_node_ptr
69 } else {
70 unsafe {
71 (*self.rear).next = Some(Box::from_raw(new_node_ptr));
72 self.rear = new_node_ptr
73 }
74 }
75
76 self.size += 1;
77 }
78
79 /// Removes and returns the value at the front of the `Queue`.
80 ///
81 /// # Examples
82 ///
83 /// ```
84 /// use dsa::data_structures::queue::Queue;
85 /// let mut queue = Queue::new();
86 /// queue.enqueue(10);
87 /// queue.enqueue(20);
88 /// assert_eq!(queue.dequeue(), Some(10));
89 /// assert_eq!(queue.dequeue(), Some(20));
90 /// assert!(queue.dequeue().is_none());
91 /// ```
92 pub fn dequeue(&mut self) -> Option<T> {
93 if self.front.is_none() {
94 return None;
95 }
96
97 let old_front = self.front.take().unwrap();
98 self.front = old_front.next;
99 if self.front.is_none() {
100 self.rear = std::ptr::null_mut();
101 }
102
103 self.size -= 1;
104
105 Some(old_front.value)
106 }
107
108 /// Returns a reference to the value at the front without removing it.
109 ///
110 /// # Examples
111 ///
112 /// ```
113 /// use dsa::data_structures::queue::Queue;
114 /// let mut queue = Queue::new();
115 /// queue.enqueue(10);
116 /// queue.enqueue(20);
117 /// assert_eq!(queue.peek(), Some(&10));
118 /// ```
119 pub fn peek(&self) -> Option<&T> {
120 self.front.as_ref().map(|node| &node.value)
121 }
122
123 /// Checks if the `Queue` is empty.
124 ///
125 /// # Examples
126 ///
127 /// ```
128 /// use dsa::data_structures::queue::Queue;
129 /// let mut queue = Queue::new();
130 /// assert!(queue.is_empty());
131 /// queue.enqueue(10);
132 /// assert!(!queue.is_empty());
133 /// ```
134 pub fn is_empty(&self) -> bool {
135 self.size == 0
136 }
137
138 /// Returns the current size of the `Queue`.
139 ///
140 /// # Examples
141 ///
142 /// ```
143 /// use dsa::data_structures::queue::Queue;
144 /// let mut queue: Queue<i32> = Queue::new();
145 /// queue.enqueue(10);
146 /// queue.enqueue(20);
147 /// queue.dequeue();
148 /// assert_eq!(queue.size(), 1);
149 /// ```
150 pub fn size(&self) -> usize {
151 self.size
152 }
153}