Skip to content

Instantly share code, notes, and snippets.

@yanil3500
Created March 7, 2019 02:36
Show Gist options
  • Save yanil3500/19f6d79566682af8acb831b7f0b86a23 to your computer and use it in GitHub Desktop.
Save yanil3500/19f6d79566682af8acb831b7f0b86a23 to your computer and use it in GitHub Desktop.
Max Heap Java Implementation
public class Heap {
private static int ROOT = 1;
private static int DEFAULT_SIZE = 3;
Integer[] elements;
int numberOfElements;
public Heap() {
this.numberOfElements = 0;
this.elements = new Integer[DEFAULT_SIZE];
}
/**
* Adds given data to the end of the heap and reorganizes the heap so the newly added element is in the
* correct position.
*
* @param toAdd
*/
public void add(Integer toAdd) {
if (this.numberOfElements == this.elements.length - 1) {
resize();
}
//increment to next available space
this.numberOfElements = this.numberOfElements + 1;
//place toAdd in the next available space
this.elements[this.numberOfElements] = toAdd;
//reorganize elements such that the heap properties are not violated
siftUp(this.numberOfElements);
}
/**
* Reorganizes the newly added element such that the heap property is not violated; This is done by:
* 1. Comparing the element at the given position (usually the position of the newly added element) with its parent;
* stops if the elements are in their correct positions.
* 2. If not, swaps the element at the given position with its parent and repeats step 1.
*
* @param position
*/
private void siftUp(int position) {
//sift up all elements excluding the root
int parentPosition = getParentPosition(position);
if (position > ROOT) {
if (isChildLargerThanParent(position, parentPosition)) {
swap(position, parentPosition);
siftUp(parentPosition);
}
}
}
/**
* Returns the element with highest priority (at the ROOT) and reorganizes the heap such that an existing element
* within the heap takes the place of the root, otherwise returns null if empty.
*
* @return
*/
public Integer remove() {
if (isEmpty()) {
return null;
}
Integer toReturn = this.elements[ROOT];
//update this.numberOfElements
this.numberOfElements = this.numberOfElements - 1;
//swap last element up to the root
swap(ROOT, this.numberOfElements);
//reorganize elements such that the heap properties are not violated
siftDown(ROOT);
return toReturn;
}
/**
* Reorganizes the newly added element such that the heap property is not violated; This is done by:
* 1. Comparing the element at the given position with its children;
* stops if the elements are in their correct positions.
* 2. If not, swaps the element at the given position with one of its children (which ever is the largest) and
* repeats step 1.
*
* @param position
*/
private void siftDown(int position) {
int positionOfLargestChild = getPositionOfLargestChild(position);
if (positionOfLargestChild != position) {
swap(position, positionOfLargestChild);
siftDown(positionOfLargestChild);
}
}
/**
* NOTE: This method was added to improve readability.
* Returns the position of the largest child.
*
* @param position
* @return
*/
private Integer getPositionOfLargestChild(int position) {
int leftChildPosition = getLeftChildPosition(position);
int rightChildPosition = getRightChildPosition(position);
int positionOfLargestChild = position;
if (isIndexInBounds(leftChildPosition)) {
if (isChildLargerThanParent(leftChildPosition, positionOfLargestChild)) {
positionOfLargestChild = leftChildPosition;
}
}
if (isIndexInBounds(rightChildPosition)) {
if (isChildLargerThanParent(rightChildPosition, positionOfLargestChild)) {
positionOfLargestChild = rightChildPosition;
}
}
return positionOfLargestChild;
}
/**
* NOTE: This method was added to improve readability.
* Helper method that does bounds checking.
*
* @param index
* @return
*/
private boolean isIndexInBounds(int index) {
return index < this.numberOfElements;
}
/**
* NOTE: This method was added to improve readability.
* Returns a boolean indicating if the child is larger than the parent.
*
* @param child
* @param position
* @return
*/
private boolean isChildLargerThanParent(int child, int position) {
return this.elements[child] > this.elements[position];
}
/**
* Swaps elements at the given indices i and j
*
* @param i
* @param j
*/
private void swap(int i, int j) {
Integer temp = this.elements[i];
this.elements[i] = this.elements[j];
this.elements[j] = temp;
}
/**
* NOTE: This method was added to improve readability.
* Calculates the position of the left child based on given index.
*
* @param index
* @return
*/
private int getLeftChildPosition(int index) {
return 2 * index;
}
/**
* NOTE: This method was added to improve readability.
* Calculates the position of the right child based on given index.
*
* @param index
* @return
*/
private int getRightChildPosition(int index) {
return 2 * index + 1;
}
/**
* NOTE: This method was added to improve readability.
* Calculates the position of the parent based on given index.
*
* @param index
* @return
*/
private int getParentPosition(int index) {
return index / 2;
}
/**
* Allocates an array that is twice as large as the current elements array, copies all of the elements to the
* new array, and reassigns the elements pointer to the new array
*/
private void resize() {
int size = this.numberOfElements * DEFAULT_SIZE;
Integer[] temp = new Integer[size];
for (int i = 1; i <= this.numberOfElements; i++) {
temp[i] = this.elements[i];
}
this.elements = temp;
}
/**
* Returns true if number of elements is equal to 0, otherwise returns false.
*
* @return
*/
public boolean isEmpty() {
return this.numberOfElements == 0;
}
/**
* Returns number indicating how large the heap is.
*
* @return
*/
public int size() {
return this.numberOfElements;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment