Created
March 7, 2019 02:36
-
-
Save yanil3500/19f6d79566682af8acb831b7f0b86a23 to your computer and use it in GitHub Desktop.
Max Heap Java Implementation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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