Browse Source

Created a BinaryHeap and JUnit tests for it.

master
jrtechs 6 years ago
parent
commit
a89368d3c7
5 changed files with 331 additions and 1 deletions
  1. +45
    -1
      src/main/java/net/jrtechs/www/DataStructures/Lists/ArrayList/ArrayBackedList.java
  2. +160
    -0
      src/main/java/net/jrtechs/www/DataStructures/Trees/Heap/BinaryHeap.java
  3. +33
    -0
      src/main/java/net/jrtechs/www/DataStructures/Trees/Heap/IHeap.java
  4. +2
    -0
      src/test/java/net/jrtechs/www/DataStructures/Lists/ArrayListTest.java
  5. +91
    -0
      src/test/java/net/jrtechs/www/DataStructures/trees/BinaryHeapTest.java

+ 45
- 1
src/main/java/net/jrtechs/www/DataStructures/Lists/ArrayList/ArrayBackedList.java View File

@ -165,6 +165,50 @@ public class ArrayBackedList implements IList
@Override @Override
public E get(int index) public E get(int index)
{ {
return (E)dataList[index];
return (E)this.dataList[index];
}
/**
* Sets an element in the array list
*
* @Warning This can go out of bounds with bad input
*
* @param index of desired element
* @return element of a specific index
*/
public void set(int index, E o)
{
this.dataList[index] = o;
}
/**
* Swaps two elements in the list by their index
*
* @param index1 index of first element
* @param index2 index of second element
*/
public void swap(int index1, int index2)
{
Object temp = this.dataList[index1];
this.dataList[index1] = dataList[index2];
this.dataList[index2] = temp;
}
/**
* Creates a string representation of the list.
*
* @return string corresponding to the list
*/
public String toString()
{
String s = "";
for(int i = 0; i < this.currentSize; i++)
{
s+= this.dataList[i] + ", ";
}
return s;
} }
} }

+ 160
- 0
src/main/java/net/jrtechs/www/DataStructures/Trees/Heap/BinaryHeap.java View File

@ -0,0 +1,160 @@
package net.jrtechs.www.DataStructures.Trees.Heap;
import net.jrtechs.www.DataStructures.Lists.ArrayList.ArrayBackedList;
/**
* Basic implementation of a {@link IHeap}. By default, this is
* a min heap, however, using the second constructor with
* (BinaryHeap.MAX_HEAP) will create a max heap. To keep the
* performance of using an array, while having a dynamically scalable
* heap, {@link ArrayBackedList} was used since it.
*
* Operation complexities:
* insertion: O(logN)
* delete extrema: O(logN)
* get extrema: O(1)
*
* Basic Heap Operations:
* Parent index = (i-1)/2 or (i-2)/2
* Left Node = 2n + 1
* Right Node = 2n + 1
*
* @author Jeffery Russell 8-26-18
*/
public class BinaryHeap<E extends Comparable>
implements IHeap<E>
{
/** Used to define comparisons for a Max heap */
public static final int MAX_HEAP = -1;
/** Used to define comparisons for a Min heap */
public static final int MIN_HEAP = 1;
/** Where the heap is storing data */
private ArrayBackedList<E> data;
/** Ordering which heap is using defined by
* MAX_HEAP, and MIN_HEAP */
private int ordering;
/**
* Creates a new min Binary Heap
*/
public BinaryHeap()
{
this.data = new ArrayBackedList<>();
this.ordering = MIN_HEAP;
}
/**
* Creates a new binary heap with a specific ordering defined by
* the MAX_HEAP, and MIN_HEAP constants
*
* @param ordering type of ordering to use
*/
public BinaryHeap(int ordering)
{
this.ordering = ordering;
this.data = new ArrayBackedList<>();
}
/**
* Inserts a new element at the end of the array, and then shifts it
* up to perserve the order of the heap.
*
* @param o element to insert
*/
@Override
public void insert(E o)
{
this.data.add(o);
this.shiftUp(this.data.size() -1);
}
/**
* Preserves structure of heap after a element has been
* added to the end of the heap.
*
* @param nodeIndex index of node to recursively bring up
*/
private void shiftUp(int nodeIndex)
{
if(nodeIndex != 0)
{
int parentIndex = (nodeIndex -1)/2;
if(data.get(parentIndex).compareTo(data.get(nodeIndex)) == ordering)
{
data.swap(nodeIndex, parentIndex);
shiftUp(parentIndex);
}
}
}
/**
* Preserves the order of heap after the top element has been
* removed.
*
* @param i index of element to recursively heapify
*/
private void heapify(int i)
{
int left = 2 * i + 1;
int right = 2 * i + 2;
int extrema = (left < data.size() &&
data.get(left).compareTo(data.get(i)) != ordering)
? left : i;
extrema = (right < data.size() &&
data.get(right).compareTo(data.get(extrema)) != ordering)
? right: extrema;
if(extrema != i)
{
this.data.swap(i, extrema);
heapify(extrema);
}
}
/**
* Removes the top element of the heap.
*
* @return top element
*/
@Override
public E remove()
{
if(this.data.size() == 0)
return null;
E element = this.data.get(0);
this.data.set(0, this.data.remove(this.data.size() -1));
this.heapify(0);
return element;
}
/**
* Returns the min/max value of the heep
*
* @return extrema value
*/
@Override
public E peek()
{
if(data.size() == 0)
return null;
return data.get(0);
}
}

+ 33
- 0
src/main/java/net/jrtechs/www/DataStructures/Trees/Heap/IHeap.java View File

@ -0,0 +1,33 @@
package net.jrtechs.www.DataStructures.Trees.Heap;
/**
* Definition for behavior of heaps
*
* @author Jeffery Russell 8-26-18
*/
public interface IHeap<E extends Comparable>
{
/**
* Add element to heap.
*
* @param o
*/
public void insert(E o);
/**
* Remove top element from heap
*
* @return top element
*/
public E remove();
/**
* Fetches top element
*
* @return top element
*/
public E peek();
}

+ 2
- 0
src/test/java/net/jrtechs/www/DataStructures/Lists/ArrayListTest.java View File

@ -7,6 +7,7 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
/** /**
* JUnit tests for {@link ArrayBackedList} * JUnit tests for {@link ArrayBackedList}
* *
@ -92,6 +93,7 @@ public class ArrayListTest
assertTrue(list.contains(13.0)); assertTrue(list.contains(13.0));
} }
/** /**
* Tests linked deletion based on element * Tests linked deletion based on element
*/ */

+ 91
- 0
src/test/java/net/jrtechs/www/DataStructures/trees/BinaryHeapTest.java View File

@ -0,0 +1,91 @@
package net.jrtechs.www.DataStructures.trees;
import net.jrtechs.www.DataStructures.Trees.Heap.BinaryHeap;
import org.junit.Test;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
/**
* JUnit tests for binary heap
*
* @author Jeffery Russell 8-26-18
*/
public class BinaryHeapTest
{
@Test
public void testCreation()
{
BinaryHeap<Double> heap = new BinaryHeap<>();
assertNotNull(heap);
}
@Test
public void testInsertion()
{
BinaryHeap<Double> heap = new BinaryHeap<>();
heap.insert(12.9);
heap.insert(12.8);
assertTrue(heap.peek() == 12.8);
}
@Test
public void testRemoval()
{
BinaryHeap<Double> heap = new BinaryHeap<>();
heap.insert(1.5);
heap.insert(-9.8);
heap.insert(999.0);
heap.remove();
heap.remove();
heap.remove();
assertNull(heap.remove());
}
@Test
public void testMinOrdering()
{
BinaryHeap<Double> heap = new BinaryHeap<>(BinaryHeap.MIN_HEAP);
heap.insert(2.0); //
heap.insert(-4.0); //
heap.insert(69.0);
heap.insert(-99.0); //
heap.insert(1.0); //
heap.insert(3.0); //
heap.insert(99.0);
assertTrue(heap.remove() == -99.0);
assertTrue(heap.remove() == -4.0);
assertTrue(heap.remove() == 1.0);
assertTrue(heap.remove() == 2.0);
assertTrue(heap.remove() == 3.0);
assertTrue(heap.remove() == 69.0);
assertTrue(heap.remove() == 99.0);
}
@Test
public void testMaxOrdering()
{
BinaryHeap<Double> heap = new BinaryHeap<>(BinaryHeap.MAX_HEAP);
heap.insert(1.0);
heap.insert(3.0);
heap.insert(2.0);
heap.insert(-4.0);
heap.insert(99.0);
assertTrue(heap.remove() == 99.0);
assertTrue(heap.remove() == 3.0);
assertTrue(heap.remove() == 2.0);
assertTrue(heap.remove() == 1.0);
assertTrue(heap.remove() == -4.0);
assertNull(heap.remove());
}
}

Loading…
Cancel
Save