Heap Sort
- Time Complexity - O(nlogn)
- We use min-heap if we want to sort in ascending order and max heap if we want to sort in descending order.
- We insert one by one into the heap, heapifying from bottom to top while inserting in order to maintain corresponding heap property.
- Now, after all elements are insered into the heap, we extract elements one by one.
- Remember- we can only extract the root of a heap.
- Also, after extraction, we put the last element in the level order traversal of heap as the new root and again heapify from top to bottom this time, in order to maintain the corresponding heap property.
- It is not a stable sort
__________________________________________________________________________________________________________________________________________________________________
public class Main {
int[] heapArr;
int endOfHeap;
Main(int size){
this.heapArr=new int[size];
this.endOfHeap=0;
}
public void initializeHeapArr(){
if(this.endOfHeap==0){
for(int i=0;i<this.heapArr.length;i++){
this.heapArr[i]=Integer.MIN_VALUE;
}
}
}
public void levelOrderTraversal(){
if(this.endOfHeap==0){
System.out.println("Heap is empty, can't traverse");
return;
}
for(int i=1;i<=this.endOfHeap;i++){
System.out.print(this.heapArr[i]+" ");
}
System.out.println();
}
public void insertIntoHeap(int data){
if(this.endOfHeap==(this.heapArr.length-1)){
System.out.println("Heap is full, can't insert '"+data+"'");
return;
}
endOfHeap++;
this.heapArr[this.endOfHeap]=data;
// now heapify bottom to top
// first we have to find its parent
int currentParentIndex= -1; // if left children then parent index will be (children's index /2) and if right child (children's index -1 /2). In any case (children's index /2) will give us parent index as Java will round it off
int currentChildIndex = this.endOfHeap;
while(currentChildIndex>=1){
currentParentIndex = currentChildIndex/2;
if(this.heapArr[currentChildIndex]<this.heapArr[currentParentIndex]){
// move up or swap
int temp = this.heapArr[currentChildIndex];
this.heapArr[currentChildIndex] = this.heapArr[currentParentIndex];
this.heapArr[currentParentIndex]=temp;
}
else{
break;
}
currentChildIndex = currentParentIndex;
}
}
public int extractMinFromHeap(){
if(this.endOfHeap==0){
System.out.println("Can't extract node, as heap is empty");
return Integer.MIN_VALUE;
}
int minValue = this.heapArr[1];
// now make the last node in level order traversal of binary heap as the new root of binary heap
this.heapArr[1]=this.heapArr[this.endOfHeap];
// now delete the last node, as we have promoted it to be the new root
this.heapArr[this.endOfHeap]=Integer.MIN_VALUE;
this.endOfHeap--;
// Now heapify from top to bottom
int currentParentIndex=1;
// find which child of the two is minimum, the child having the minimum value will become the candidate for swap if it has value less than root obviously
while(currentParentIndex<this.endOfHeap){
int currentChildIndex=-1;
int leftChildIndex = 2*currentParentIndex;
int rightChildIndex = (2*currentParentIndex)+1;
int leftChildValue=Integer.MIN_VALUE;
int rightChildValue = Integer.MIN_VALUE;
if(leftChildIndex <= this.endOfHeap){
leftChildValue=this.heapArr[leftChildIndex];
}
if(rightChildIndex <= this.endOfHeap){
rightChildValue = this.heapArr[rightChildIndex];
}
// if no child is there
if(leftChildValue==Integer.MIN_VALUE && rightChildValue== Integer.MIN_VALUE) {
break;
}
// if left child is not there
if(leftChildValue==Integer.MIN_VALUE && rightChildValue!= Integer.MIN_VALUE){
currentChildIndex=rightChildIndex;
}
// if right child is not there
else if(rightChildValue==Integer.MIN_VALUE && leftChildValue!=Integer.MIN_VALUE){
currentChildIndex=leftChildIndex;
}
// if both child is present
else{
if(leftChildValue<=rightChildValue){
currentChildIndex = leftChildIndex;
}
else{
currentChildIndex = rightChildIndex;
}
}
if(this.heapArr[currentParentIndex]>this.heapArr[currentChildIndex]){
int temp = this.heapArr[currentParentIndex];
this.heapArr[currentParentIndex]=this.heapArr[currentChildIndex];
this.heapArr[currentChildIndex]=temp;
}
else{
break;
}
currentParentIndex=currentChildIndex;
// levelOrderTraversal();
}
// System.out.println();
return minValue;
}
public static void main(String[] args) throws Exception {
Main minHeap = new Main(15);
minHeap.initializeHeapArr();
minHeap.levelOrderTraversal();
int[] arr={1,4,4,5,6,2,3,90,120,43,0};
System.out.println("UnSorted Array :");
for(int i=0;i<arr.length;i++){
System.out.print(arr[i]+" ");
}
for(int i=0;i<arr.length;i++){
minHeap.insertIntoHeap(arr[i]);
}
System.out.println();
System.out.println("Min Heap initial Level order traversal...");
minHeap.levelOrderTraversal();
// System.out.println("extractMinFromHeap...");
// System.out.println(minHeap.extractMinFromHeap());
// System.out.println();
// System.out.println("Level order traversal...");
// minHeap.levelOrderTraversal();
// for(int i=0;i<arr.length;i++){
// arr[i]=minHeap.extractMinFromHeap();
// }
System.out.println("Sorted Array :");
for(int i=0;i<arr.length;i++){
System.out.print(minHeap.extractMinFromHeap()+" ");
}
}
}
Output:
Heap is empty, can't traverse
UnSorted Array :
1 4 4 5 6 2 3 90 120 43 0
Min Heap initial Level order traversal...
0 1 2 5 4 4 3 90 120 43 6
Sorted Array :
0 1 2 3 4 4 5 6 43 90 120
Comments
Post a Comment