Skip to content

Commit 6545688

Browse files
authored
Enhance docs, add tests in CircularQueue (#6015)
1 parent c40eb8d commit 6545688

File tree

2 files changed

+134
-31
lines changed

2 files changed

+134
-31
lines changed
Lines changed: 68 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,76 @@
11
package com.thealgorithms.datastructures.queues;
22

3-
// This program implements the concept of CircularQueue in Java
4-
// Link to the concept: (https://en.wikipedia.org/wiki/Circular_buffer)
3+
/**
4+
* The CircularQueue class represents a generic circular queue data structure that uses an array to
5+
* store elements. This queue allows efficient utilization of space by wrapping around the array,
6+
* thus avoiding the need to shift elements during enqueue and dequeue operations.
7+
*
8+
* <p>When the queue reaches its maximum capacity, further enqueues will raise an exception.
9+
* Similarly, attempts to dequeue or peek from an empty queue will also result in an exception.
10+
*
11+
* <p>Reference: <a href="https://en.wikipedia.org/wiki/Circular_buffer">Circular Buffer</a>
12+
*
13+
* <p>Usage Example:
14+
* <pre>
15+
* CircularQueue<Integer> queue = new CircularQueue<>(3);
16+
* queue.enQueue(1);
17+
* queue.enQueue(2);
18+
* queue.enQueue(3);
19+
* queue.deQueue(); // Removes 1
20+
* queue.enQueue(4); // Wraps around and places 4 at the position of removed 1
21+
* </pre>
22+
*
23+
* @param <T> the type of elements in this queue
24+
*/
525
public class CircularQueue<T> {
626
private T[] array;
727
private int topOfQueue;
828
private int beginningOfQueue;
929
private final int size;
1030
private int currentSize;
1131

32+
/**
33+
* Constructs a CircularQueue with a specified capacity.
34+
*
35+
* @param size the maximum number of elements this queue can hold
36+
* @throws IllegalArgumentException if the size is less than 1
37+
*/
1238
@SuppressWarnings("unchecked")
1339
public CircularQueue(int size) {
40+
if (size < 1) {
41+
throw new IllegalArgumentException("Size must be greater than 0");
42+
}
1443
this.array = (T[]) new Object[size];
1544
this.topOfQueue = -1;
1645
this.beginningOfQueue = -1;
1746
this.size = size;
1847
this.currentSize = 0;
1948
}
2049

50+
/**
51+
* Checks if the queue is empty.
52+
*
53+
* @return {@code true} if the queue is empty; {@code false} otherwise
54+
*/
2155
public boolean isEmpty() {
2256
return currentSize == 0;
2357
}
2458

59+
/**
60+
* Checks if the queue is full.
61+
*
62+
* @return {@code true} if the queue has reached its maximum capacity; {@code false} otherwise
63+
*/
2564
public boolean isFull() {
2665
return currentSize == size;
2766
}
2867

68+
/**
69+
* Adds a new element to the queue. If the queue is full, an exception is thrown.
70+
*
71+
* @param value the element to be added to the queue
72+
* @throws IllegalStateException if the queue is already full
73+
*/
2974
public void enQueue(T value) {
3075
if (isFull()) {
3176
throw new IllegalStateException("Queue is full");
@@ -38,12 +83,18 @@ public void enQueue(T value) {
3883
currentSize++;
3984
}
4085

86+
/**
87+
* Removes and returns the element at the front of the queue.
88+
*
89+
* @return the element at the front of the queue
90+
* @throws IllegalStateException if the queue is empty
91+
*/
4192
public T deQueue() {
4293
if (isEmpty()) {
4394
throw new IllegalStateException("Queue is empty");
4495
}
4596
T removedValue = array[beginningOfQueue];
46-
array[beginningOfQueue] = null; // Optional: Help GC
97+
array[beginningOfQueue] = null; // Optional: Nullify to help garbage collection
4798
beginningOfQueue = (beginningOfQueue + 1) % size;
4899
currentSize--;
49100
if (isEmpty()) {
@@ -53,49 +104,35 @@ public T deQueue() {
53104
return removedValue;
54105
}
55106

107+
/**
108+
* Returns the element at the front of the queue without removing it.
109+
*
110+
* @return the element at the front of the queue
111+
* @throws IllegalStateException if the queue is empty
112+
*/
56113
public T peek() {
57114
if (isEmpty()) {
58115
throw new IllegalStateException("Queue is empty");
59116
}
60117
return array[beginningOfQueue];
61118
}
62119

120+
/**
121+
* Deletes the entire queue by resetting all elements and pointers.
122+
*/
63123
public void deleteQueue() {
64124
array = null;
65125
beginningOfQueue = -1;
66126
topOfQueue = -1;
67127
currentSize = 0;
68128
}
69129

130+
/**
131+
* Returns the current number of elements in the queue.
132+
*
133+
* @return the number of elements currently in the queue
134+
*/
70135
public int size() {
71136
return currentSize;
72137
}
73-
74-
public static void main(String[] args) {
75-
CircularQueue<Integer> cq = new CircularQueue<>(5);
76-
System.out.println(cq.isEmpty()); // true
77-
System.out.println(cq.isFull()); // false
78-
cq.enQueue(1);
79-
cq.enQueue(2);
80-
cq.enQueue(3);
81-
cq.enQueue(4);
82-
cq.enQueue(5);
83-
84-
System.out.println(cq.deQueue()); // 1
85-
System.out.println(cq.deQueue()); // 2
86-
System.out.println(cq.deQueue()); // 3
87-
System.out.println(cq.deQueue()); // 4
88-
System.out.println(cq.deQueue()); // 5
89-
90-
System.out.println(cq.isFull()); // false
91-
System.out.println(cq.isEmpty()); // true
92-
cq.enQueue(6);
93-
cq.enQueue(7);
94-
cq.enQueue(8);
95-
96-
System.out.println(cq.peek()); // 6
97-
System.out.println(cq.peek()); // 6
98-
99-
cq.deleteQueue();
100-
}
101138
}

src/test/java/com/thealgorithms/datastructures/queues/CircularQueueTest.java

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,4 +103,70 @@ void testSize() {
103103
cq.deQueue();
104104
assertEquals(1, cq.size());
105105
}
106+
107+
@Test
108+
void testCircularWrapAround() {
109+
CircularQueue<Integer> cq = new CircularQueue<>(3);
110+
cq.enQueue(1);
111+
cq.enQueue(2);
112+
cq.enQueue(3);
113+
114+
cq.deQueue();
115+
cq.enQueue(4);
116+
117+
assertEquals(2, cq.deQueue());
118+
assertEquals(3, cq.deQueue());
119+
assertEquals(4, cq.deQueue());
120+
assertTrue(cq.isEmpty());
121+
}
122+
123+
@Test
124+
void testEnQueueDeQueueMultipleTimes() {
125+
CircularQueue<Integer> cq = new CircularQueue<>(3);
126+
cq.enQueue(1);
127+
cq.enQueue(2);
128+
cq.deQueue();
129+
cq.enQueue(3);
130+
cq.enQueue(4);
131+
132+
assertTrue(cq.isFull());
133+
assertEquals(2, cq.deQueue());
134+
assertEquals(3, cq.deQueue());
135+
assertEquals(4, cq.deQueue());
136+
assertTrue(cq.isEmpty());
137+
}
138+
139+
@Test
140+
void testMultipleWrapArounds() {
141+
CircularQueue<Integer> cq = new CircularQueue<>(3);
142+
cq.enQueue(1);
143+
cq.deQueue();
144+
cq.enQueue(2);
145+
cq.deQueue();
146+
cq.enQueue(3);
147+
cq.deQueue();
148+
cq.enQueue(4);
149+
150+
assertEquals(4, cq.peek());
151+
}
152+
153+
@Test
154+
void testSizeDuringOperations() {
155+
CircularQueue<Integer> cq = new CircularQueue<>(3);
156+
assertEquals(0, cq.size());
157+
158+
cq.enQueue(1);
159+
cq.enQueue(2);
160+
assertEquals(2, cq.size());
161+
162+
cq.deQueue();
163+
assertEquals(1, cq.size());
164+
165+
cq.enQueue(3);
166+
cq.enQueue(4);
167+
assertEquals(3, cq.size());
168+
cq.deQueue();
169+
cq.deQueue();
170+
assertEquals(1, cq.size());
171+
}
106172
}

0 commit comments

Comments
 (0)