From e756a7d2d50287b74b1a88cfa578e457f709821f Mon Sep 17 00:00:00 2001 From: Alex Klymenko Date: Wed, 21 Aug 2024 12:26:21 +0200 Subject: [PATCH] refactor: `CircularQueue` (#5354) --- .../datastructures/queues/CircularQueue.java | 120 +++++++++--------- .../queues/CircularQueueTest.java | 106 ++++++++++++++++ 2 files changed, 163 insertions(+), 63 deletions(-) create mode 100644 src/test/java/com/thealgorithms/datastructures/queues/CircularQueueTest.java diff --git a/src/main/java/com/thealgorithms/datastructures/queues/CircularQueue.java b/src/main/java/com/thealgorithms/datastructures/queues/CircularQueue.java index 48d9ffe9..c67817a6 100644 --- a/src/main/java/com/thealgorithms/datastructures/queues/CircularQueue.java +++ b/src/main/java/com/thealgorithms/datastructures/queues/CircularQueue.java @@ -2,106 +2,100 @@ package com.thealgorithms.datastructures.queues; // This program implements the concept of CircularQueue in Java // Link to the concept: (https://en.wikipedia.org/wiki/Circular_buffer) -public class CircularQueue { - - int[] arr; - int topOfQueue; - int beginningOfQueue; - int size; +public class CircularQueue { + private T[] array; + private int topOfQueue; + private int beginningOfQueue; + private final int size; + private int currentSize; + @SuppressWarnings("unchecked") public CircularQueue(int size) { - arr = new int[size]; - topOfQueue = -1; - beginningOfQueue = -1; + this.array = (T[]) new Object[size]; + this.topOfQueue = -1; + this.beginningOfQueue = -1; this.size = size; + this.currentSize = 0; } public boolean isEmpty() { - return beginningOfQueue == -1; + return currentSize == 0; } public boolean isFull() { - if (topOfQueue + 1 == beginningOfQueue) { - return true; - } else { - return topOfQueue == size - 1 && beginningOfQueue == 0; - } + return currentSize == size; } - public void enQueue(int value) { + public void enQueue(T value) { if (isFull()) { - System.out.println("The Queue is full!"); - } else if (isEmpty()) { + throw new IllegalStateException("Queue is full"); + } + if (isEmpty()) { beginningOfQueue = 0; - topOfQueue++; - arr[topOfQueue] = value; - System.out.println(value + " has been successfully inserted!"); - } else { - if (topOfQueue + 1 == size) { - topOfQueue = 0; - } else { - topOfQueue++; - } - arr[topOfQueue] = value; - System.out.println(value + " has been successfully inserted!"); } + topOfQueue = (topOfQueue + 1) % size; + array[topOfQueue] = value; + currentSize++; } - public int deQueue() { + public T deQueue() { if (isEmpty()) { - System.out.println("The Queue is Empty!"); - return -1; - } else { - int res = arr[beginningOfQueue]; - arr[beginningOfQueue] = Integer.MIN_VALUE; - if (beginningOfQueue == topOfQueue) { - beginningOfQueue = -1; - topOfQueue = -1; - } else if (beginningOfQueue + 1 == size) { - beginningOfQueue = 0; - } else { - beginningOfQueue++; - } - return res; + throw new IllegalStateException("Queue is empty"); } + T removedValue = array[beginningOfQueue]; + array[beginningOfQueue] = null; // Optional: Help GC + beginningOfQueue = (beginningOfQueue + 1) % size; + currentSize--; + if (isEmpty()) { + beginningOfQueue = -1; + topOfQueue = -1; + } + return removedValue; } - public int peek() { + public T peek() { if (isEmpty()) { - System.out.println("The Queue is Empty!"); - return -1; - } else { - return arr[beginningOfQueue]; + throw new IllegalStateException("Queue is empty"); } + return array[beginningOfQueue]; } public void deleteQueue() { - arr = null; - System.out.println("The Queue is deleted!"); + array = null; + beginningOfQueue = -1; + topOfQueue = -1; + currentSize = 0; + } + + public int size() { + return currentSize; } public static void main(String[] args) { - CircularQueue cq = new CircularQueue(5); - System.out.println(cq.isEmpty()); - System.out.println(cq.isFull()); + CircularQueue cq = new CircularQueue<>(5); + System.out.println(cq.isEmpty()); // true + System.out.println(cq.isFull()); // false cq.enQueue(1); cq.enQueue(2); cq.enQueue(3); cq.enQueue(4); cq.enQueue(5); - System.out.println(cq.deQueue()); - System.out.println(cq.deQueue()); - System.out.println(cq.deQueue()); - System.out.println(cq.deQueue()); - System.out.println(cq.deQueue()); - System.out.println(cq.isFull()); - System.out.println(cq.isEmpty()); + System.out.println(cq.deQueue()); // 1 + System.out.println(cq.deQueue()); // 2 + System.out.println(cq.deQueue()); // 3 + System.out.println(cq.deQueue()); // 4 + System.out.println(cq.deQueue()); // 5 + + System.out.println(cq.isFull()); // false + System.out.println(cq.isEmpty()); // true cq.enQueue(6); cq.enQueue(7); cq.enQueue(8); - System.out.println(cq.peek()); - System.out.println(cq.peek()); + + System.out.println(cq.peek()); // 6 + System.out.println(cq.peek()); // 6 + cq.deleteQueue(); } } diff --git a/src/test/java/com/thealgorithms/datastructures/queues/CircularQueueTest.java b/src/test/java/com/thealgorithms/datastructures/queues/CircularQueueTest.java new file mode 100644 index 00000000..71dca8fd --- /dev/null +++ b/src/test/java/com/thealgorithms/datastructures/queues/CircularQueueTest.java @@ -0,0 +1,106 @@ +package com.thealgorithms.datastructures.queues; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +class CircularQueueTest { + + @Test + void testEnQueue() { + CircularQueue cq = new CircularQueue<>(3); + cq.enQueue(1); + cq.enQueue(2); + cq.enQueue(3); + + assertEquals(1, cq.peek()); + assertTrue(cq.isFull()); + } + + @Test + void testDeQueue() { + CircularQueue cq = new CircularQueue<>(3); + cq.enQueue(1); + cq.enQueue(2); + cq.enQueue(3); + + assertEquals(1, cq.deQueue()); + assertEquals(2, cq.peek()); + assertFalse(cq.isFull()); + } + + @Test + void testIsEmpty() { + CircularQueue cq = new CircularQueue<>(3); + assertTrue(cq.isEmpty()); + + cq.enQueue(1); + assertFalse(cq.isEmpty()); + } + + @Test + void testIsFull() { + CircularQueue cq = new CircularQueue<>(2); + cq.enQueue(1); + cq.enQueue(2); + assertTrue(cq.isFull()); + + cq.deQueue(); + assertFalse(cq.isFull()); + } + + @Test + void testPeek() { + CircularQueue cq = new CircularQueue<>(3); + cq.enQueue(1); + cq.enQueue(2); + + assertEquals(1, cq.peek()); + assertEquals(1, cq.peek()); // Ensure peek doesn't remove the element + } + + @Test + void testDeleteQueue() { + CircularQueue cq = new CircularQueue<>(3); + cq.enQueue(1); + cq.enQueue(2); + cq.deleteQueue(); + + org.junit.jupiter.api.Assertions.assertThrows(IllegalStateException.class, cq::peek); + } + + @Test + void testEnQueueOnFull() { + CircularQueue cq = new CircularQueue<>(2); + cq.enQueue(1); + cq.enQueue(2); + + org.junit.jupiter.api.Assertions.assertThrows(IllegalStateException.class, () -> cq.enQueue(3)); + } + + @Test + void testDeQueueOnEmpty() { + CircularQueue cq = new CircularQueue<>(2); + org.junit.jupiter.api.Assertions.assertThrows(IllegalStateException.class, cq::deQueue); + } + + @Test + void testPeekOnEmpty() { + CircularQueue cq = new CircularQueue<>(2); + org.junit.jupiter.api.Assertions.assertThrows(IllegalStateException.class, cq::peek); + } + + @Test + void testSize() { + CircularQueue cq = new CircularQueue<>(3); + cq.enQueue(1); + cq.enQueue(2); + + assertEquals(2, cq.size()); + + cq.deQueue(); + assertEquals(1, cq.size()); + } +}