Update tests for PriorityQueue.
This commit is contained in:
parent
c5518e7240
commit
d05bc92689
@ -1,236 +1,15 @@
|
|||||||
package org.insa.algo.utils;
|
package org.insa.algo.utils;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
public class BinaryHeapTest extends PriorityQueueTest {
|
||||||
import static org.junit.Assert.assertFalse;
|
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
@Override
|
||||||
import java.util.HashSet;
|
public PriorityQueue<MutableInteger> createQueue() {
|
||||||
import java.util.stream.IntStream;
|
return new BinaryHeap<>();
|
||||||
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
public class BinaryHeapTest {
|
|
||||||
|
|
||||||
class MutableInteger implements Comparable<MutableInteger> {
|
|
||||||
|
|
||||||
// Actual value
|
|
||||||
private int value;
|
|
||||||
|
|
||||||
public MutableInteger(int value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return The integer value stored inside this MutableInteger.
|
|
||||||
*/
|
|
||||||
public int get() {
|
|
||||||
return this.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Update the integer value stored inside this MutableInteger.
|
|
||||||
*
|
|
||||||
* @param value New value to set.
|
|
||||||
*/
|
|
||||||
public void set(int value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int compareTo(MutableInteger other) {
|
public PriorityQueue<MutableInteger> createQueue(PriorityQueue<MutableInteger> queue) {
|
||||||
return Integer.compare(this.value, other.value);
|
return new BinaryHeap<>((BinaryHeap<MutableInteger>) queue);
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
// Raw data arrays.
|
|
||||||
private MutableInteger[] data1 = IntStream.range(0, 20).mapToObj(MutableInteger::new)
|
|
||||||
.toArray(MutableInteger[]::new);
|
|
||||||
private MutableInteger[] data2 = Arrays.stream(new int[] { 8, 1, 6, 3, 4, 5, 9 })
|
|
||||||
.mapToObj(MutableInteger::new).toArray(MutableInteger[]::new);
|
|
||||||
|
|
||||||
// Actual heap.
|
|
||||||
private BinaryHeap<MutableInteger> heap1, heap2;
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void init() {
|
|
||||||
// Create the range heap
|
|
||||||
this.heap1 = new BinaryHeap<>();
|
|
||||||
this.heap2 = new BinaryHeap<>();
|
|
||||||
|
|
||||||
for (MutableInteger v: data1) {
|
|
||||||
this.heap1.insert(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (MutableInteger v: data2) {
|
|
||||||
this.heap2.insert(v);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testIsEmpty() {
|
|
||||||
BinaryHeap<MutableInteger> tree = new BinaryHeap<>();
|
|
||||||
assertTrue(tree.isEmpty());
|
|
||||||
assertFalse(this.heap1.isEmpty());
|
|
||||||
assertFalse(this.heap2.isEmpty());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testSize() {
|
|
||||||
BinaryHeap<MutableInteger> tree = new BinaryHeap<>();
|
|
||||||
assertEquals(0, tree.size());
|
|
||||||
assertEquals(20, this.heap1.size());
|
|
||||||
assertEquals(7, this.heap2.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testInsert() {
|
|
||||||
BinaryHeap<MutableInteger> heap = new BinaryHeap<>();
|
|
||||||
int size = 0;
|
|
||||||
for (MutableInteger x: data1) {
|
|
||||||
heap.insert(x);
|
|
||||||
assertEquals(++size, heap.size());
|
|
||||||
}
|
|
||||||
assertEquals(data1.length, heap.size());
|
|
||||||
|
|
||||||
heap = new BinaryHeap<>();
|
|
||||||
size = 0;
|
|
||||||
for (MutableInteger x: data2) {
|
|
||||||
heap.insert(x);
|
|
||||||
assertEquals(++size, heap.size());
|
|
||||||
}
|
|
||||||
assertEquals(data2.length, heap.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = EmptyPriorityQueueException.class)
|
|
||||||
public void testEmptyFindMin() {
|
|
||||||
BinaryHeap<MutableInteger> heap = new BinaryHeap<>();
|
|
||||||
heap.findMin();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testFindMin() {
|
|
||||||
assertEquals(0, heap1.findMin().get());
|
|
||||||
assertEquals(1, heap2.findMin().get());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = EmptyPriorityQueueException.class)
|
|
||||||
public void testEmptyDeleteMin() {
|
|
||||||
BinaryHeap<MutableInteger> heap = new BinaryHeap<>();
|
|
||||||
heap.deleteMin();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testDeleteMin() {
|
|
||||||
// range 1 (sorted)
|
|
||||||
int size = data1.length;
|
|
||||||
assertEquals(heap1.size(), size);
|
|
||||||
for (MutableInteger x: data1) {
|
|
||||||
assertEquals(x, heap1.deleteMin());
|
|
||||||
size -= 1;
|
|
||||||
assertEquals(size, heap1.size());
|
|
||||||
}
|
|
||||||
assertEquals(0, heap1.size());
|
|
||||||
assertTrue(heap1.isEmpty());
|
|
||||||
|
|
||||||
// range 2 (was not sorted)
|
|
||||||
MutableInteger[] range2 = Arrays.copyOf(data2, data2.length);
|
|
||||||
Arrays.sort(range2);
|
|
||||||
size = range2.length;
|
|
||||||
assertEquals(heap2.size(), size);
|
|
||||||
for (MutableInteger x: range2) {
|
|
||||||
assertEquals(x.get(), heap2.deleteMin().get());
|
|
||||||
size -= 1;
|
|
||||||
assertEquals(size, heap2.size());
|
|
||||||
}
|
|
||||||
assertEquals(0, heap2.size());
|
|
||||||
assertTrue(heap2.isEmpty());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = ElementNotFoundException.class)
|
|
||||||
public void testRemoveEmpty() {
|
|
||||||
BinaryHeap<MutableInteger> heap = new BinaryHeap<>();
|
|
||||||
heap.remove(new MutableInteger(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = ElementNotFoundException.class)
|
|
||||||
public void testRemoveNotFound() {
|
|
||||||
heap1.remove(new MutableInteger(20));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testRemove() {
|
|
||||||
// heap 1
|
|
||||||
int size1 = heap1.size();
|
|
||||||
int[] deleteOrder1 = new int[] { 12, 17, 18, 19, 4, 5, 3, 2, 0, 9, 10, 16, 8, 14, 13, 15, 7,
|
|
||||||
6, 1, 11 };
|
|
||||||
for (int i = 0; i < deleteOrder1.length; ++i) {
|
|
||||||
// Remove from structure
|
|
||||||
heap1.remove(this.data1[deleteOrder1[i]]);
|
|
||||||
|
|
||||||
// Copy the remaining elements
|
|
||||||
BinaryHeap<MutableInteger> copyTree = new BinaryHeap<>(heap1);
|
|
||||||
|
|
||||||
// Retrieve all remaining elements in both structures
|
|
||||||
MutableInteger[] remains_in = new MutableInteger[deleteOrder1.length - i - 1],
|
|
||||||
remains_cp = new MutableInteger[deleteOrder1.length - i - 1];
|
|
||||||
for (int j = 0; j < remains_cp.length; ++j) {
|
|
||||||
remains_in[j] = this.data1[deleteOrder1[i + j + 1]];
|
|
||||||
remains_cp[j] = copyTree.deleteMin();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check that the copy is now empty, and that both list contains all
|
|
||||||
// elements.
|
|
||||||
assertTrue(copyTree.isEmpty());
|
|
||||||
assertEquals(new HashSet<>(Arrays.asList(remains_in)),
|
|
||||||
new HashSet<>(Arrays.asList(remains_cp)));
|
|
||||||
|
|
||||||
// Check that the size of the original tree is correct.
|
|
||||||
assertEquals(--size1, heap1.size());
|
|
||||||
}
|
|
||||||
assertTrue(heap1.isEmpty());
|
|
||||||
|
|
||||||
// heap 2
|
|
||||||
int size2 = heap2.size();
|
|
||||||
int[] deleteOrder2 = new int[] { 6, 5, 0, 1, 4, 2, 3 };
|
|
||||||
for (int i = 0; i < deleteOrder2.length; ++i) {
|
|
||||||
// Remove from structure
|
|
||||||
heap2.remove(this.data2[deleteOrder2[i]]);
|
|
||||||
|
|
||||||
// Copy the remaining elements
|
|
||||||
BinaryHeap<MutableInteger> copyTree = new BinaryHeap<>(heap2);
|
|
||||||
|
|
||||||
// Retrieve all remaining elements in both structures
|
|
||||||
MutableInteger[] remains_in = new MutableInteger[deleteOrder2.length - i - 1],
|
|
||||||
remains_cp = new MutableInteger[deleteOrder2.length - i - 1];
|
|
||||||
for (int j = 0; j < remains_cp.length; ++j) {
|
|
||||||
remains_in[j] = this.data2[deleteOrder2[i + j + 1]];
|
|
||||||
remains_cp[j] = copyTree.deleteMin();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check that the copy is now empty, and that both list contains all
|
|
||||||
// elements.
|
|
||||||
assertTrue(copyTree.isEmpty());
|
|
||||||
assertEquals(new HashSet<>(Arrays.asList(remains_in)),
|
|
||||||
new HashSet<>(Arrays.asList(remains_cp)));
|
|
||||||
|
|
||||||
// Check that the size of the original tree is correct.
|
|
||||||
assertEquals(--size2, heap2.size());
|
|
||||||
}
|
|
||||||
assertTrue(heap2.isEmpty());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testRemoveThenAdd() {
|
|
||||||
MutableInteger mi5 = this.data1[6];
|
|
||||||
heap1.remove(mi5);
|
|
||||||
assertEquals(19, heap1.size());
|
|
||||||
mi5.set(-20);
|
|
||||||
heap1.insert(mi5);
|
|
||||||
assertEquals(20, heap1.size());
|
|
||||||
assertEquals(-20, heap1.findMin().get());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,236 +1,15 @@
|
|||||||
package org.insa.algo.utils;
|
package org.insa.algo.utils;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
public class BinarySearchTreeTest extends PriorityQueueTest {
|
||||||
import static org.junit.Assert.assertFalse;
|
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
@Override
|
||||||
import java.util.HashSet;
|
public PriorityQueue<MutableInteger> createQueue() {
|
||||||
import java.util.stream.IntStream;
|
return new BinarySearchTree<>();
|
||||||
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
public class BinarySearchTreeTest {
|
|
||||||
|
|
||||||
class MutableInteger implements Comparable<MutableInteger> {
|
|
||||||
|
|
||||||
// Actual value
|
|
||||||
private int value;
|
|
||||||
|
|
||||||
public MutableInteger(int value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return The integer value stored inside this MutableInteger.
|
|
||||||
*/
|
|
||||||
public int get() {
|
|
||||||
return this.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Update the integer value stored inside this MutableInteger.
|
|
||||||
*
|
|
||||||
* @param value New value to set.
|
|
||||||
*/
|
|
||||||
public void set(int value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int compareTo(MutableInteger other) {
|
public PriorityQueue<MutableInteger> createQueue(PriorityQueue<MutableInteger> queue) {
|
||||||
return Integer.compare(this.value, other.value);
|
return new BinarySearchTree<>((BinarySearchTree<MutableInteger>) queue);
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
// Raw data arrays.
|
|
||||||
private MutableInteger[] data1 = IntStream.range(0, 20).mapToObj(MutableInteger::new)
|
|
||||||
.toArray(MutableInteger[]::new);
|
|
||||||
private MutableInteger[] data2 = Arrays.stream(new int[] { 8, 1, 6, 3, 4, 5, 9 })
|
|
||||||
.mapToObj(MutableInteger::new).toArray(MutableInteger[]::new);
|
|
||||||
|
|
||||||
// Actual searchTree.
|
|
||||||
private BinarySearchTree<MutableInteger> searchTree1, searchTree2;
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void init() {
|
|
||||||
// Create the range searchTree
|
|
||||||
this.searchTree1 = new BinarySearchTree<>();
|
|
||||||
this.searchTree2 = new BinarySearchTree<>();
|
|
||||||
|
|
||||||
for (MutableInteger v: data1) {
|
|
||||||
this.searchTree1.insert(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (MutableInteger v: data2) {
|
|
||||||
this.searchTree2.insert(v);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testIsEmpty() {
|
|
||||||
BinarySearchTree<MutableInteger> tree = new BinarySearchTree<>();
|
|
||||||
assertTrue(tree.isEmpty());
|
|
||||||
assertFalse(this.searchTree1.isEmpty());
|
|
||||||
assertFalse(this.searchTree2.isEmpty());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testSize() {
|
|
||||||
BinarySearchTree<MutableInteger> tree = new BinarySearchTree<>();
|
|
||||||
assertEquals(0, tree.size());
|
|
||||||
assertEquals(20, this.searchTree1.size());
|
|
||||||
assertEquals(7, this.searchTree2.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testInsert() {
|
|
||||||
BinarySearchTree<MutableInteger> searchTree = new BinarySearchTree<>();
|
|
||||||
int size = 0;
|
|
||||||
for (MutableInteger x: data1) {
|
|
||||||
searchTree.insert(x);
|
|
||||||
assertEquals(++size, searchTree.size());
|
|
||||||
}
|
|
||||||
assertEquals(data1.length, searchTree.size());
|
|
||||||
|
|
||||||
searchTree = new BinarySearchTree<>();
|
|
||||||
size = 0;
|
|
||||||
for (MutableInteger x: data2) {
|
|
||||||
searchTree.insert(x);
|
|
||||||
assertEquals(++size, searchTree.size());
|
|
||||||
}
|
|
||||||
assertEquals(data2.length, searchTree.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = EmptyPriorityQueueException.class)
|
|
||||||
public void testEmptyFindMin() {
|
|
||||||
BinarySearchTree<MutableInteger> searchTree = new BinarySearchTree<>();
|
|
||||||
searchTree.findMin();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testFindMin() {
|
|
||||||
assertEquals(0, searchTree1.findMin().get());
|
|
||||||
assertEquals(1, searchTree2.findMin().get());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = EmptyPriorityQueueException.class)
|
|
||||||
public void testEmptyDeleteMin() {
|
|
||||||
BinarySearchTree<MutableInteger> searchTree = new BinarySearchTree<>();
|
|
||||||
searchTree.deleteMin();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testDeleteMin() {
|
|
||||||
// range 1 (sorted)
|
|
||||||
int size = data1.length;
|
|
||||||
assertEquals(searchTree1.size(), size);
|
|
||||||
for (MutableInteger x: data1) {
|
|
||||||
assertEquals(x, searchTree1.deleteMin());
|
|
||||||
size -= 1;
|
|
||||||
assertEquals(size, searchTree1.size());
|
|
||||||
}
|
|
||||||
assertEquals(0, searchTree1.size());
|
|
||||||
assertTrue(searchTree1.isEmpty());
|
|
||||||
|
|
||||||
// range 2 (was not sorted)
|
|
||||||
MutableInteger[] range2 = Arrays.copyOf(data2, data2.length);
|
|
||||||
Arrays.sort(range2);
|
|
||||||
size = range2.length;
|
|
||||||
assertEquals(searchTree2.size(), size);
|
|
||||||
for (MutableInteger x: range2) {
|
|
||||||
assertEquals(x.get(), searchTree2.deleteMin().get());
|
|
||||||
size -= 1;
|
|
||||||
assertEquals(size, searchTree2.size());
|
|
||||||
}
|
|
||||||
assertEquals(0, searchTree2.size());
|
|
||||||
assertTrue(searchTree2.isEmpty());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = ElementNotFoundException.class)
|
|
||||||
public void testRemoveEmpty() {
|
|
||||||
BinarySearchTree<MutableInteger> searchTree = new BinarySearchTree<>();
|
|
||||||
searchTree.remove(new MutableInteger(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = ElementNotFoundException.class)
|
|
||||||
public void testRemoveNotFound() {
|
|
||||||
searchTree1.remove(new MutableInteger(20));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testRemove() {
|
|
||||||
// searchTree 1
|
|
||||||
int size1 = searchTree1.size();
|
|
||||||
int[] deleteOrder1 = new int[] { 12, 17, 18, 19, 4, 5, 3, 2, 0, 9, 10, 16, 8, 14, 13, 15, 7,
|
|
||||||
6, 1, 11 };
|
|
||||||
for (int i = 0; i < deleteOrder1.length; ++i) {
|
|
||||||
// Remove from structure
|
|
||||||
searchTree1.remove(this.data1[deleteOrder1[i]]);
|
|
||||||
|
|
||||||
// Copy the remaining elements
|
|
||||||
BinarySearchTree<MutableInteger> copyTree = new BinarySearchTree<>(searchTree1);
|
|
||||||
|
|
||||||
// Retrieve all remaining elements in both structures
|
|
||||||
MutableInteger[] remains_in = new MutableInteger[deleteOrder1.length - i - 1],
|
|
||||||
remains_cp = new MutableInteger[deleteOrder1.length - i - 1];
|
|
||||||
for (int j = 0; j < remains_cp.length; ++j) {
|
|
||||||
remains_in[j] = this.data1[deleteOrder1[i + j + 1]];
|
|
||||||
remains_cp[j] = copyTree.deleteMin();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check that the copy is now empty, and that both list contains all
|
|
||||||
// elements.
|
|
||||||
assertTrue(copyTree.isEmpty());
|
|
||||||
assertEquals(new HashSet<>(Arrays.asList(remains_in)),
|
|
||||||
new HashSet<>(Arrays.asList(remains_cp)));
|
|
||||||
|
|
||||||
// Check that the size of the original tree is correct.
|
|
||||||
assertEquals(--size1, searchTree1.size());
|
|
||||||
}
|
|
||||||
assertTrue(searchTree1.isEmpty());
|
|
||||||
|
|
||||||
// searchTree 2
|
|
||||||
int size2 = searchTree2.size();
|
|
||||||
int[] deleteOrder2 = new int[] { 6, 5, 0, 1, 4, 2, 3 };
|
|
||||||
for (int i = 0; i < deleteOrder2.length; ++i) {
|
|
||||||
// Remove from structure
|
|
||||||
searchTree2.remove(this.data2[deleteOrder2[i]]);
|
|
||||||
|
|
||||||
// Copy the remaining elements
|
|
||||||
BinarySearchTree<MutableInteger> copyTree = new BinarySearchTree<>(searchTree2);
|
|
||||||
|
|
||||||
// Retrieve all remaining elements in both structures
|
|
||||||
MutableInteger[] remains_in = new MutableInteger[deleteOrder2.length - i - 1],
|
|
||||||
remains_cp = new MutableInteger[deleteOrder2.length - i - 1];
|
|
||||||
for (int j = 0; j < remains_cp.length; ++j) {
|
|
||||||
remains_in[j] = this.data2[deleteOrder2[i + j + 1]];
|
|
||||||
remains_cp[j] = copyTree.deleteMin();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check that the copy is now empty, and that both list contains all
|
|
||||||
// elements.
|
|
||||||
assertTrue(copyTree.isEmpty());
|
|
||||||
assertEquals(new HashSet<>(Arrays.asList(remains_in)),
|
|
||||||
new HashSet<>(Arrays.asList(remains_cp)));
|
|
||||||
|
|
||||||
// Check that the size of the original tree is correct.
|
|
||||||
assertEquals(--size2, searchTree2.size());
|
|
||||||
}
|
|
||||||
assertTrue(searchTree2.isEmpty());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testRemoveThenAdd() {
|
|
||||||
MutableInteger mi5 = this.data1[6];
|
|
||||||
searchTree1.remove(mi5);
|
|
||||||
assertEquals(19, searchTree1.size());
|
|
||||||
mi5.set(-20);
|
|
||||||
searchTree1.insert(mi5);
|
|
||||||
assertEquals(20, searchTree1.size());
|
|
||||||
assertEquals(-20, searchTree1.findMin().get());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
259
src/test/org/insa/algo/utils/PriorityQueueTest.java
Normal file
259
src/test/org/insa/algo/utils/PriorityQueueTest.java
Normal file
@ -0,0 +1,259 @@
|
|||||||
|
package org.insa.algo.utils;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.IntStream;
|
||||||
|
|
||||||
|
import org.junit.Assume;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.junit.runners.Parameterized;
|
||||||
|
import org.junit.runners.Parameterized.Parameter;
|
||||||
|
import org.junit.runners.Parameterized.Parameters;
|
||||||
|
|
||||||
|
@RunWith(Parameterized.class)
|
||||||
|
public abstract class PriorityQueueTest {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Needs to be implemented by child class to actually provide priority queue
|
||||||
|
* implementation.
|
||||||
|
*
|
||||||
|
* @return A new instance of a PriorityQueue implementation.
|
||||||
|
*/
|
||||||
|
public abstract PriorityQueue<MutableInteger> createQueue();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Needs to be implemented by child class to actually provide priority queue
|
||||||
|
* implementation.
|
||||||
|
*
|
||||||
|
* @param queue Queue to copy.
|
||||||
|
*
|
||||||
|
* @return Copy of the given queue.
|
||||||
|
*/
|
||||||
|
public abstract PriorityQueue<MutableInteger> createQueue(PriorityQueue<MutableInteger> queue);
|
||||||
|
|
||||||
|
protected static class MutableInteger implements Comparable<MutableInteger> {
|
||||||
|
|
||||||
|
// Actual value
|
||||||
|
private int value;
|
||||||
|
|
||||||
|
public MutableInteger(int value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The integer value stored inside this MutableInteger.
|
||||||
|
*/
|
||||||
|
public int get() {
|
||||||
|
return this.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the integer value stored inside this MutableInteger.
|
||||||
|
*
|
||||||
|
* @param value New value to set.
|
||||||
|
*/
|
||||||
|
public void set(int value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(MutableInteger other) {
|
||||||
|
return Integer.compare(this.value, other.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
protected static class TestParameters<E extends Comparable<E>> {
|
||||||
|
|
||||||
|
// Data to insert
|
||||||
|
public final E[] data;
|
||||||
|
public final int[] deleteOrder;
|
||||||
|
|
||||||
|
public TestParameters(E[] data, int[] deleteOrder) {
|
||||||
|
this.data = data;
|
||||||
|
this.deleteOrder = deleteOrder;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set of parameters.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Parameters
|
||||||
|
public static Collection<Object> data() {
|
||||||
|
Collection<Object> objects = new ArrayList<>();
|
||||||
|
objects.add(new TestParameters<>(new MutableInteger[0], new int[0]));
|
||||||
|
objects.add(new TestParameters<>(
|
||||||
|
IntStream.range(0, 50).mapToObj(MutableInteger::new).toArray(MutableInteger[]::new),
|
||||||
|
IntStream.range(0, 50).toArray()));
|
||||||
|
objects.add(new TestParameters<>(
|
||||||
|
IntStream.range(0, 20).mapToObj(MutableInteger::new).toArray(MutableInteger[]::new),
|
||||||
|
new int[] { 12, 17, 18, 19, 4, 5, 3, 2, 0, 9, 10, 16, 8, 14, 13, 15, 7, 6, 1,
|
||||||
|
11 }));
|
||||||
|
objects.add(
|
||||||
|
new TestParameters<>(
|
||||||
|
Arrays.stream(new int[] { 8, 1, 6, 3, 4, 5, 9 })
|
||||||
|
.mapToObj(MutableInteger::new).toArray(MutableInteger[]::new),
|
||||||
|
new int[] { 6, 5, 0, 1, 4, 2, 3 }));
|
||||||
|
return objects;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Parameter
|
||||||
|
public TestParameters<MutableInteger> parameters;
|
||||||
|
|
||||||
|
// Actual queue.
|
||||||
|
private PriorityQueue<MutableInteger> queue;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void init() {
|
||||||
|
// Create the range queue
|
||||||
|
this.queue = createQueue();
|
||||||
|
|
||||||
|
for (MutableInteger v: parameters.data) {
|
||||||
|
this.queue.insert(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIsEmpty() {
|
||||||
|
assertEquals(parameters.data.length == 0, this.queue.isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSize() {
|
||||||
|
assertEquals(parameters.data.length, this.queue.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testInsert() {
|
||||||
|
PriorityQueue<MutableInteger> queue = createQueue();
|
||||||
|
int size = 0;
|
||||||
|
for (MutableInteger x: parameters.data) {
|
||||||
|
queue.insert(x);
|
||||||
|
assertEquals(++size, queue.size());
|
||||||
|
}
|
||||||
|
assertEquals(parameters.data.length, queue.size());
|
||||||
|
MutableInteger[] range = Arrays.copyOf(parameters.data, parameters.data.length);
|
||||||
|
Arrays.sort(range);
|
||||||
|
|
||||||
|
for (MutableInteger mi: range) {
|
||||||
|
assertEquals(mi.get(), queue.deleteMin().value);
|
||||||
|
assertEquals(--size, queue.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = EmptyPriorityQueueException.class)
|
||||||
|
public void testEmptyFindMin() {
|
||||||
|
Assume.assumeTrue(queue.isEmpty());
|
||||||
|
queue.findMin();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFindMin() {
|
||||||
|
Assume.assumeFalse(queue.isEmpty());
|
||||||
|
assertEquals(Collections.min(Arrays.asList(parameters.data)).get(), queue.findMin().get());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = EmptyPriorityQueueException.class)
|
||||||
|
public void testEmptyDeleteMin() {
|
||||||
|
Assume.assumeTrue(queue.isEmpty());
|
||||||
|
queue.deleteMin();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDeleteMin() {
|
||||||
|
int size = parameters.data.length;
|
||||||
|
assertEquals(queue.size(), size);
|
||||||
|
MutableInteger[] range = Arrays.copyOf(parameters.data, parameters.data.length);
|
||||||
|
Arrays.sort(range);
|
||||||
|
for (MutableInteger x: range) {
|
||||||
|
assertEquals(x, queue.deleteMin());
|
||||||
|
size -= 1;
|
||||||
|
assertEquals(size, queue.size());
|
||||||
|
}
|
||||||
|
assertEquals(0, queue.size());
|
||||||
|
assertTrue(queue.isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = ElementNotFoundException.class)
|
||||||
|
public void testRemoveEmpty() {
|
||||||
|
Assume.assumeTrue(queue.isEmpty());
|
||||||
|
queue.remove(new MutableInteger(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = ElementNotFoundException.class)
|
||||||
|
public void testRemoveNotFound() {
|
||||||
|
Assume.assumeFalse(queue.isEmpty());
|
||||||
|
List<MutableInteger> data = Arrays.asList(parameters.data);
|
||||||
|
queue.remove(new MutableInteger(Collections.min(data).get() - 1));
|
||||||
|
queue.remove(new MutableInteger(Collections.max(data).get() + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = ElementNotFoundException.class)
|
||||||
|
public void testDeleteThenRemove() {
|
||||||
|
Assume.assumeFalse(queue.isEmpty());
|
||||||
|
MutableInteger min = queue.deleteMin();
|
||||||
|
queue.remove(min);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = ElementNotFoundException.class)
|
||||||
|
public void testRemoveTwice() {
|
||||||
|
Assume.assumeFalse(queue.isEmpty());
|
||||||
|
queue.remove(parameters.data[4 % parameters.data.length]);
|
||||||
|
queue.remove(parameters.data[4 % parameters.data.length]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRemove() {
|
||||||
|
int size1 = queue.size();
|
||||||
|
for (int i = 0; i < parameters.deleteOrder.length; ++i) {
|
||||||
|
// Remove from structure
|
||||||
|
queue.remove(parameters.data[parameters.deleteOrder[i]]);
|
||||||
|
|
||||||
|
// Copy the remaining elements
|
||||||
|
PriorityQueue<MutableInteger> copyTree = createQueue(queue);
|
||||||
|
|
||||||
|
// Retrieve all remaining elements in both structures
|
||||||
|
ArrayList<MutableInteger> remains_in = new ArrayList<>(),
|
||||||
|
remains_cp = new ArrayList<>();
|
||||||
|
for (int j = i + 1; j < parameters.deleteOrder.length; ++j) {
|
||||||
|
remains_in.add(parameters.data[parameters.deleteOrder[j]]);
|
||||||
|
remains_cp.add(copyTree.deleteMin());
|
||||||
|
}
|
||||||
|
Collections.sort(remains_in);
|
||||||
|
|
||||||
|
// Check that the copy is now empty, and that both list contains all
|
||||||
|
// elements.
|
||||||
|
assertTrue(copyTree.isEmpty());
|
||||||
|
assertEquals(remains_in, remains_cp);
|
||||||
|
|
||||||
|
// Check that the size of the original tree is correct.
|
||||||
|
assertEquals(--size1, queue.size());
|
||||||
|
}
|
||||||
|
assertTrue(queue.isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRemoveThenAdd() {
|
||||||
|
Assume.assumeFalse(queue.isEmpty());
|
||||||
|
int min = Collections.min(Arrays.asList(parameters.data)).get();
|
||||||
|
for (MutableInteger mi: parameters.data) {
|
||||||
|
queue.remove(mi);
|
||||||
|
assertEquals(parameters.data.length - 1, queue.size());
|
||||||
|
mi.set(--min);
|
||||||
|
queue.insert(mi);
|
||||||
|
assertEquals(parameters.data.length, queue.size());
|
||||||
|
assertEquals(min, queue.findMin().get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user