IntQueue
This commit is contained in:
parent
a3c111b5f5
commit
c6c6fffac9
111
src/main/java/com/dataStructures/IntQueue.java
Normal file
111
src/main/java/com/dataStructures/IntQueue.java
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
package com.dataStructures;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This file contains an implementation of an integer only queue which is extremely quick and
|
||||||
|
* lightweight. In terms of performance it can outperform java.util.ArrayDeque (Java's fastest queue
|
||||||
|
* implementation) by a factor of 40+! See the benchmark test below for proof. However, the downside
|
||||||
|
* is you need to know an upper bound on the number of elements that will be inside the queue at any
|
||||||
|
* given time for this queue to work.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
public class IntQueue {
|
||||||
|
|
||||||
|
private int[] ar;
|
||||||
|
private int front, end, sz;
|
||||||
|
|
||||||
|
// maxSize is the maximum number of items
|
||||||
|
// that can be in the queue at any given time
|
||||||
|
public IntQueue(int maxSize) {
|
||||||
|
front = end = 0;
|
||||||
|
sz = maxSize + 1;
|
||||||
|
ar = new int[sz];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return true/false on whether the queue is empty
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return front == end;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the number of elements inside the queue
|
||||||
|
public int size() {
|
||||||
|
if (front > end) return (end + sz - front);
|
||||||
|
return end - front;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int peek() {
|
||||||
|
return ar[front];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add an element to the queue
|
||||||
|
public void enqueue(int value) {
|
||||||
|
ar[end] = value;
|
||||||
|
if (++end == sz) end = 0;
|
||||||
|
if (end == front) throw new RuntimeException("Queue too small!");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure you check is the queue is not empty before calling dequeue!
|
||||||
|
public int dequeue() {
|
||||||
|
int ret_val = ar[front];
|
||||||
|
if (++front == sz) front = 0;
|
||||||
|
return ret_val;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Example usage to check the how fast this implementation is
|
||||||
|
public static void main(String[] args) {
|
||||||
|
|
||||||
|
IntQueue q = new IntQueue(5);
|
||||||
|
|
||||||
|
q.enqueue(1);
|
||||||
|
q.enqueue(2);
|
||||||
|
q.enqueue(3);
|
||||||
|
q.enqueue(4);
|
||||||
|
q.enqueue(5);
|
||||||
|
|
||||||
|
System.out.println(q.dequeue()); // 1
|
||||||
|
System.out.println(q.dequeue()); // 2
|
||||||
|
System.out.println(q.dequeue()); // 3
|
||||||
|
System.out.println(q.dequeue()); // 4
|
||||||
|
|
||||||
|
System.out.println(q.isEmpty()); // false
|
||||||
|
|
||||||
|
q.enqueue(1);
|
||||||
|
q.enqueue(2);
|
||||||
|
q.enqueue(3);
|
||||||
|
|
||||||
|
System.out.println(q.dequeue()); // 5
|
||||||
|
System.out.println(q.dequeue()); // 1
|
||||||
|
System.out.println(q.dequeue()); // 2
|
||||||
|
System.out.println(q.dequeue()); // 3
|
||||||
|
|
||||||
|
System.out.println(q.isEmpty()); // true
|
||||||
|
|
||||||
|
benchMarkTest();
|
||||||
|
}
|
||||||
|
|
||||||
|
// BenchMark IntQueue vs ArrayDeque.
|
||||||
|
private static void benchMarkTest() {
|
||||||
|
|
||||||
|
int n = 10000000;
|
||||||
|
IntQueue intQ = new IntQueue(n);
|
||||||
|
|
||||||
|
// IntQueue times at around 0.0324 seconds
|
||||||
|
long start = System.nanoTime();
|
||||||
|
for (int i = 0; i < n; i++) intQ.enqueue(i);
|
||||||
|
for (int i = 0; i < n; i++) intQ.dequeue();
|
||||||
|
long end = System.nanoTime();
|
||||||
|
System.out.println("IntQueue Time: " + (end - start) / 1e9);
|
||||||
|
|
||||||
|
// ArrayDeque times at around 1.438 seconds
|
||||||
|
java.util.ArrayDeque<Integer> arrayDeque = new java.util.ArrayDeque<>();
|
||||||
|
// java.util.ArrayDeque <Integer> arrayDeque = new java.util.ArrayDeque<>(n); // strangely the
|
||||||
|
// ArrayQueue is slower when you give it an initial capacity.
|
||||||
|
start = System.nanoTime();
|
||||||
|
for (int i = 0; i < n; i++) arrayDeque.offer(i);
|
||||||
|
for (int i = 0; i < n; i++) arrayDeque.poll();
|
||||||
|
end = System.nanoTime();
|
||||||
|
System.out.println("ArrayDeque Time: " + (end - start) / 1e9);
|
||||||
|
}
|
||||||
|
}
|
128
src/test/java/com/dataStructures/IntQueueTest.java
Normal file
128
src/test/java/com/dataStructures/IntQueueTest.java
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
package com.dataStructures;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class IntQueueTest {
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setup() {}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEmptyQueue() {
|
||||||
|
IntQueue queue = new IntQueue(0);
|
||||||
|
assertTrue(queue.isEmpty());
|
||||||
|
assertEquals(queue.size(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEnqueueOneElement() {
|
||||||
|
IntQueue queue = new IntQueue(1);
|
||||||
|
queue.enqueue(77);
|
||||||
|
assertEquals(queue.size(), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAll() {
|
||||||
|
int n = 5;
|
||||||
|
IntQueue queue = new IntQueue(10);
|
||||||
|
assertTrue(queue.isEmpty());
|
||||||
|
for (int i = 1; i <= n; i++) {
|
||||||
|
queue.enqueue(i);
|
||||||
|
assertFalse(queue.isEmpty());
|
||||||
|
}
|
||||||
|
for (int i = 1; i <= n; i++) {
|
||||||
|
assertEquals(i, queue.peek());
|
||||||
|
assertEquals(i, queue.dequeue());
|
||||||
|
assertEquals(queue.size(), n - i);
|
||||||
|
}
|
||||||
|
assertTrue(queue.isEmpty());
|
||||||
|
n = 8;
|
||||||
|
for (int i = 1; i <= n; i++) {
|
||||||
|
queue.enqueue(i);
|
||||||
|
assertFalse(queue.isEmpty());
|
||||||
|
}
|
||||||
|
for (int i = 1; i <= n; i++) {
|
||||||
|
assertEquals(i, queue.peek());
|
||||||
|
assertEquals(i, queue.dequeue());
|
||||||
|
assertEquals(queue.size(), n - i);
|
||||||
|
}
|
||||||
|
assertTrue(queue.isEmpty());
|
||||||
|
n = 9;
|
||||||
|
for (int i = 1; i <= n; i++) {
|
||||||
|
queue.enqueue(i);
|
||||||
|
assertFalse(queue.isEmpty());
|
||||||
|
}
|
||||||
|
for (int i = 1; i <= n; i++) {
|
||||||
|
assertEquals(i, queue.peek());
|
||||||
|
assertEquals(i, queue.dequeue());
|
||||||
|
assertEquals(queue.size(), n - i);
|
||||||
|
}
|
||||||
|
assertTrue(queue.isEmpty());
|
||||||
|
n = 10;
|
||||||
|
for (int i = 1; i <= n; i++) {
|
||||||
|
queue.enqueue(i);
|
||||||
|
assertFalse(queue.isEmpty());
|
||||||
|
}
|
||||||
|
for (int i = 1; i <= n; i++) {
|
||||||
|
assertEquals(i, queue.peek());
|
||||||
|
assertEquals(i, queue.dequeue());
|
||||||
|
assertEquals(queue.size(), n - i);
|
||||||
|
}
|
||||||
|
assertTrue(queue.isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPeekOneElement() {
|
||||||
|
IntQueue queue = new IntQueue(1);
|
||||||
|
queue.enqueue(77);
|
||||||
|
assertTrue(queue.peek() == 77);
|
||||||
|
assertEquals(queue.size(), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDequeueOneElement() {
|
||||||
|
IntQueue queue = new IntQueue(1);
|
||||||
|
queue.enqueue(77);
|
||||||
|
assertTrue(queue.dequeue() == 77);
|
||||||
|
assertEquals(queue.size(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRandom() {
|
||||||
|
|
||||||
|
for (int qSize = 1; qSize <= 50; qSize++) {
|
||||||
|
|
||||||
|
IntQueue intQ = new IntQueue(qSize);
|
||||||
|
ArrayDeque<Integer> javaQ = new ArrayDeque<>(qSize);
|
||||||
|
|
||||||
|
assertEquals(javaQ.isEmpty(), intQ.isEmpty());
|
||||||
|
assertEquals(javaQ.size(), intQ.size());
|
||||||
|
|
||||||
|
for (int operations = 0; operations < 5000; operations++) {
|
||||||
|
|
||||||
|
double r = Math.random();
|
||||||
|
|
||||||
|
if (r < 0.60) {
|
||||||
|
int elem = (int) (1000 * Math.random());
|
||||||
|
if (javaQ.size() < qSize) {
|
||||||
|
javaQ.offer(elem);
|
||||||
|
intQ.enqueue(elem);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!javaQ.isEmpty()) {
|
||||||
|
assertEquals((int) javaQ.poll(), (int) intQ.dequeue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEquals(javaQ.isEmpty(), intQ.isEmpty());
|
||||||
|
assertEquals(javaQ.size(), intQ.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user