Update tests for PriorityQueue.
This commit is contained in:
		@@ -1,236 +1,15 @@
 | 
			
		||||
package org.insa.algo.utils;
 | 
			
		||||
 | 
			
		||||
import static org.junit.Assert.assertEquals;
 | 
			
		||||
import static org.junit.Assert.assertFalse;
 | 
			
		||||
import static org.junit.Assert.assertTrue;
 | 
			
		||||
public class BinaryHeapTest extends PriorityQueueTest {
 | 
			
		||||
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
import java.util.HashSet;
 | 
			
		||||
import java.util.stream.IntStream;
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
        public int compareTo(MutableInteger other) {
 | 
			
		||||
            return Integer.compare(this.value, other.value);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    // 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);
 | 
			
		||||
        }
 | 
			
		||||
    @Override
 | 
			
		||||
    public PriorityQueue<MutableInteger> createQueue() {
 | 
			
		||||
        return new BinaryHeap<>();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @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());
 | 
			
		||||
    @Override
 | 
			
		||||
    public PriorityQueue<MutableInteger> createQueue(PriorityQueue<MutableInteger> queue) {
 | 
			
		||||
        return new BinaryHeap<>((BinaryHeap<MutableInteger>) queue);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,236 +1,15 @@
 | 
			
		||||
package org.insa.algo.utils;
 | 
			
		||||
 | 
			
		||||
import static org.junit.Assert.assertEquals;
 | 
			
		||||
import static org.junit.Assert.assertFalse;
 | 
			
		||||
import static org.junit.Assert.assertTrue;
 | 
			
		||||
public class BinarySearchTreeTest extends PriorityQueueTest {
 | 
			
		||||
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
import java.util.HashSet;
 | 
			
		||||
import java.util.stream.IntStream;
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
        public int compareTo(MutableInteger other) {
 | 
			
		||||
            return Integer.compare(this.value, other.value);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    // 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);
 | 
			
		||||
        }
 | 
			
		||||
    @Override
 | 
			
		||||
    public PriorityQueue<MutableInteger> createQueue() {
 | 
			
		||||
        return new BinarySearchTree<>();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @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());
 | 
			
		||||
    @Override
 | 
			
		||||
    public PriorityQueue<MutableInteger> createQueue(PriorityQueue<MutableInteger> queue) {
 | 
			
		||||
        return new BinarySearchTree<>((BinarySearchTree<MutableInteger>) queue);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										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());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user