diff --git a/algorithms/Java/README.md b/algorithms/Java/README.md index 3590b541..621c67ef 100644 --- a/algorithms/Java/README.md +++ b/algorithms/Java/README.md @@ -78,6 +78,7 @@ - [Left View of a Tree](trees/left-view.java) - [Right View of a Tree](trees/right-view.java) - [Zig-Zag Traversal of a Tree](trees/zig-zag-traversal.java) +- [Min Heap](trees/MinHeap.java) ## Backtracking - [N Queen Problem](backtracking/nqueen.java) diff --git a/algorithms/Java/trees/MinHeap.java b/algorithms/Java/trees/MinHeap.java new file mode 100644 index 00000000..40f0336c --- /dev/null +++ b/algorithms/Java/trees/MinHeap.java @@ -0,0 +1,177 @@ +/* +Min-Heap is a binary tree structure such that every node in the tree will be +lesser or equal to the child node. It is used when you need quick access to +the smallest number in the array. +Time complexity to build the heap: O(n) +Time complexity to remove min: O(log(n)) +Time complexity to remove all elements: O(n*log(n)) +*/ + +import java.util.ArrayList; +import java.util.Collections; +import java.util.stream.Collectors; + +public class MinHeap> { + + // Example of MinHeap usage + public static void main(String[] args) { + MinHeap myHeap = new MinHeap<>(); + + // adding elements to the heap + myHeap.insert(4); + myHeap.insert(10); + myHeap.insert(2); + myHeap.insert(22); + myHeap.insert(45); + myHeap.insert(18); + + System.out.println(myHeap); + // output: 2, 10, 4, 22, 45, 18 + + myHeap.removeMin(); + System.out.println(myHeap); + // output: 4, 10, 18, 22, 45 + + myHeap.removeMin(); + System.out.println(myHeap); + // output: 10, 22, 18, 45 + + myHeap.removeMin(); + System.out.println(myHeap); + // output: 18, 22, 45 + + myHeap.removeMin(); + System.out.println(myHeap); + // output: 22, 45 + + myHeap.removeMin(); + System.out.println(myHeap); + // output: 45 + + myHeap.removeMin(); + System.out.println(myHeap); + // output: + // (empty output) + + } + + // Array representing the binary tree, + // where the first element is the smallest element and the root + ArrayList items; + + public MinHeap() { + this.items = new ArrayList<>(); + } + + /* + takes index of the node as argument, + and returns the index of its parent. + Returns -1 if the element is a root. + */ + public int getIndexOfParent(int index) { + return (index == 0) ? -1 : (index - 1) / 2; + + } + + /* + Takes index of the node as argument, + and returns the index of its first child. + The index of its second child is greater by one + than the index of the first child. + Returns -1 if the element at given index has no children + */ + public int getIndexOfFirstChild(int index) { + int result = (index * 2) + 1; + return (result >= items.size()) ? -1 : result; + } + + /* swaps the element at given index with the its parent + until the order of the heap is restored (the parent is smaller or equal) + */ + public void siftUp(int index) { + if (index == 0) return; + T element = items.get(index); + int indexOfParent = getIndexOfParent(index); + while (indexOfParent != -1 && items.get(indexOfParent).compareTo(element) > 0) { + Collections.swap(items, index, indexOfParent); + index = indexOfParent; + indexOfParent = getIndexOfParent(index); + } + } + + /* swaps the element at given index with the smallest of its children + until the order of the heap is restored (both children are greater or equal) + */ + public void siftDown(int index) { + int firstChildIndex = getIndexOfFirstChild(index); + int secondChildIndex = firstChildIndex + 1; + T element = items.get(index); + + /* minIndex is the index of the smallest child + + minIndex is the index of the first child, if the element doesn't + have children (so firstChildIndex=-1), or if the element only has one + child, or if the first child is smaller than the second child. + + minIndex is the index of the second child, if the second child + is smaller than the first child. */ + int minIndex = (firstChildIndex != -1 && + secondChildIndex < items.size() && items.get(firstChildIndex).compareTo( + items.get(secondChildIndex)) > 0) ? + secondChildIndex : firstChildIndex; + while (minIndex != -1 && element.compareTo(items.get(minIndex)) > 0) { + Collections.swap(items, minIndex, index); + index = minIndex; + firstChildIndex = getIndexOfFirstChild(index); + secondChildIndex = firstChildIndex + 1; + + /* see above for explanation of minIndex */ + minIndex = (firstChildIndex != -1 && + secondChildIndex < items.size() && items.get(firstChildIndex).compareTo( + items.get(secondChildIndex)) > 0) ? + secondChildIndex : firstChildIndex; + } + } + + /* Insert an element into the heap, preserving the correct order + of elements (children of a node have to be greater or equal to the node) */ + public void insert(T element) { + items.add(element); + siftUp(items.size() - 1); + } + + /* Remove the smallest element and return it. + The smallest element in a MinHeap + is always the root. + Correct order of elements has to be restored after removing the root. + */ + public T removeMin() { + if (items.isEmpty()) throw new IllegalStateException( + "Cannot remove an element from an empty heap!"); + + T result = items.get(0); //smallest element + + //If the heap only has one element, no reordering needed after removing + if (items.size()==1) { + items.remove(0); + return result; + } + Collections.swap(items, 0, items.size() - 1); + items.remove(items.size() - 1); + siftDown(0); + return result; + } + + public T getMin() { + return items.get(0); + } + + /* Print the elements in the heap in the order they are stored + separated by , */ + @Override + public String toString() { + return items.stream().map(Object::toString) + .collect(Collectors.joining(", ")); + } + +} diff --git a/docs/en/Tree/min-heap.md b/docs/en/Tree/min-heap.md index d09465bb..307021ab 100644 --- a/docs/en/Tree/min-heap.md +++ b/docs/en/Tree/min-heap.md @@ -43,8 +43,9 @@ ## Implementation -- [C](https://github.com/MakeContributions/DSA/blob/main/algorithms/C/tree/min-heap.c) -- [C++](https://github.com/MakeContributions/DSA/blob/main/algorithms/CPlusPlus/Trees/min-heap.cpp) +- [C](../../../algorithms/C/tree/min-heap.c) +- [C++](../../../algorithms/CPlusPlus/Trees/min-heap.cpp) +- [Java](../../../algorithms/Java/trees/MinHeap.java) ## Video URL [Youtube Video about Heaps](https://www.youtube.com/watch?v=t0Cq6tVNRBA)