Make LinkedQueue generic (#3909)

This commit is contained in:
Kumaraswamy B G 2023-03-06 00:38:42 +05:30 committed by GitHub
parent dd949e9b5d
commit 3e9dd776e5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 95 additions and 35 deletions

View File

@ -1,23 +1,25 @@
package com.thealgorithms.datastructures.queues; package com.thealgorithms.datastructures.queues;
import java.util.Iterator;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import java.util.StringJoiner;
public class LinkedQueue { public class LinkedQueue<T> implements Iterable<T> {
class Node { static class Node<T> {
int data; T data;
Node next; Node<T> next;
public Node() { public Node() {
this(0); this(null);
} }
public Node(int data) { public Node(T data) {
this(data, null); this(data, null);
} }
public Node(int data, Node next) { public Node(T data, Node<T> next) {
this.data = data; this.data = data;
this.next = next; this.next = next;
} }
@ -26,12 +28,12 @@ public class LinkedQueue {
/** /**
* Front of Queue * Front of Queue
*/ */
private Node front; private Node<T> front;
/** /**
* Rear of Queue * Rear of Queue
*/ */
private Node rear; private Node<T> rear;
/** /**
* Size of Queue * Size of Queue
@ -42,7 +44,7 @@ public class LinkedQueue {
* Init LinkedQueue * Init LinkedQueue
*/ */
public LinkedQueue() { public LinkedQueue() {
front = rear = new Node(); front = rear = new Node<>();
} }
/** /**
@ -58,15 +60,14 @@ public class LinkedQueue {
* Add element to rear of queue * Add element to rear of queue
* *
* @param data insert value * @param data insert value
* @return true if add successfully
*/ */
public boolean enqueue(int data) { public void enqueue(T data) {
Node newNode = new Node(data); Node<T> newNode = new Node<>(data);
rear.next = newNode; rear.next = newNode;
rear = newNode; rear = newNode;
/* make rear point at last node */ /* make rear point at last node */
size++; size++;
return true;
} }
/** /**
@ -74,14 +75,13 @@ public class LinkedQueue {
* *
* @return element at the front of queue * @return element at the front of queue
*/ */
public int dequeue() { public T dequeue() {
if (isEmpty()) { if (isEmpty()) {
throw new NoSuchElementException("queue is empty"); throw new NoSuchElementException("queue is empty");
} }
Node destroy = front.next; Node<T> destroy = front.next;
int retValue = destroy.data; T retValue = destroy.data;
front.next = front.next.next; front.next = front.next.next;
destroy = null;
/* clear let GC do it's work */ /* clear let GC do it's work */
size--; size--;
@ -97,7 +97,7 @@ public class LinkedQueue {
* *
* @return element at the front * @return element at the front
*/ */
public int peekFront() { public T peekFront() {
if (isEmpty()) { if (isEmpty()) {
throw new NoSuchElementException("queue is empty"); throw new NoSuchElementException("queue is empty");
} }
@ -109,13 +109,52 @@ public class LinkedQueue {
* *
* @return element at the front * @return element at the front
*/ */
public int peekRear() { public T peekRear() {
if (isEmpty()) { if (isEmpty()) {
throw new NoSuchElementException("queue is empty"); throw new NoSuchElementException("queue is empty");
} }
return rear.data; return rear.data;
} }
/**
* Peeks the element at the index and
* returns the value
* @param pos at which to peek
*/
public T peek(int pos) {
if (pos > size)
throw new IndexOutOfBoundsException(
"Position %s out of range!".formatted(pos));
Node<T> node = front;
while (pos-- > 0)
node = node.next;
return node.data;
}
/**
* Node iterator, allows to travel through
* the nodes using for() loop or forEach(Consumer)
*/
@Override
public Iterator<T> iterator() {
return new Iterator<>() {
Node<T> node = front;
@Override
public boolean hasNext() {
return node.next != null;
}
@Override
public T next() {
return (node = node.next).data;
}
};
}
/** /**
* Return size of queue * Return size of queue
* *
@ -129,30 +168,22 @@ public class LinkedQueue {
* Clear all nodes in queue * Clear all nodes in queue
*/ */
public void clear() { public void clear() {
while (!isEmpty()) { while (size > 0)
dequeue(); dequeue();
} }
}
@Override @Override
public String toString() { public String toString() {
if (isEmpty()) { StringJoiner join = new StringJoiner(", "); // separator of ', '
return "[]"; Node<T> travel = front;
} while ((travel = travel.next) != null)
StringBuilder builder = new StringBuilder(); join.add(String.valueOf(travel.data));
Node cur = front.next; return '[' + join.toString() + ']';
builder.append("[");
while (cur != null) {
builder.append(cur.data).append(", ");
cur = cur.next;
}
builder.replace(builder.length() - 2, builder.length(), "]");
return builder.toString();
} }
/* Driver Code */ /* Driver Code */
public static void main(String[] args) { public static void main(String[] args) {
LinkedQueue queue = new LinkedQueue(); LinkedQueue<Integer> queue = new LinkedQueue<>();
assert queue.isEmpty(); assert queue.isEmpty();
queue.enqueue(1); queue.enqueue(1);

View File

@ -0,0 +1,29 @@
package com.thealgorithms.datastructures.queues;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
class LinkedQueueTest {
@Test
public void testQue() {
LinkedQueue<Integer> queue = new LinkedQueue<>();
for (int i = 1; i < 5; i++)
queue.enqueue(i);
assertEquals(queue.peekRear(), 4);
assertEquals(queue.peek(2), 2);
assertEquals(queue.peek(4), 4);
final int[] element = { 1 };
// iterates over all the elements present
// as in the form of nodes
queue.forEach(integer -> {
if (element[0]++ != integer)
throw new AssertionError();
});
}
}