2016-10-09 01:41:35 +08:00
|
|
|
import java.util.Scanner;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Heap Sort Algorithm.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
public class HeapSort {
|
|
|
|
/**
|
|
|
|
* array to store heap.
|
|
|
|
*/
|
|
|
|
private int[] heap;
|
|
|
|
/**
|
|
|
|
* size of heap.
|
|
|
|
*/
|
|
|
|
private int size;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Constructor.
|
|
|
|
*
|
|
|
|
* @param heap
|
|
|
|
* array of unordered integers
|
|
|
|
*/
|
|
|
|
public HeapSort(int[] heap) {
|
|
|
|
this.setHeap(heap);
|
|
|
|
this.setSize(heap.length);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets this.size with {@code length).
|
|
|
|
*
|
|
|
|
* @param length
|
|
|
|
* integer length of heap
|
|
|
|
*/
|
|
|
|
private void setSize(int length) {
|
|
|
|
this.size = length;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets Heap with {@code heap}.
|
|
|
|
*
|
|
|
|
* @param heap
|
|
|
|
* array of unordered elements
|
|
|
|
*/
|
|
|
|
private void setHeap(int[] heap) {
|
|
|
|
this.heap = heap;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Swaps index of {@code first} with {@code second}.
|
|
|
|
*
|
|
|
|
* @param first
|
|
|
|
* index to swap {@code second} with
|
|
|
|
* @param second
|
|
|
|
* index to swap {@code first} with
|
|
|
|
*/
|
|
|
|
private void swap(int first, int second) {
|
|
|
|
int temp = this.heap[first];
|
|
|
|
this.heap[first] = this.heap[second];
|
|
|
|
this.heap[second] = temp;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Heapifies subtree from {@code top} as root to {@code last} as last child.
|
|
|
|
*
|
|
|
|
* @param rootIndex
|
|
|
|
* index of root
|
|
|
|
* @param lastChild
|
|
|
|
* index of last child
|
|
|
|
*/
|
|
|
|
private void heapSubtree(int rootIndex, int lastChild) {
|
2016-10-09 01:42:37 +08:00
|
|
|
int leftIndex = rootIndex * 2 + 1;
|
2016-10-09 01:41:35 +08:00
|
|
|
int rightIndex = rootIndex * 2 + 2;
|
|
|
|
boolean hasLeftChild = leftIndex <= lastChild;
|
|
|
|
boolean hasRightChild = rightIndex <= lastChild;
|
|
|
|
int root = this.heap[rootIndex];
|
|
|
|
if (hasRightChild) {
|
2016-10-09 01:42:37 +08:00
|
|
|
int left = this.heap[leftIndex];
|
|
|
|
int right = this.heap[rightIndex];
|
2016-10-09 01:41:35 +08:00
|
|
|
if (left < right && left < root) {
|
2016-10-09 01:42:37 +08:00
|
|
|
this.swap(leftIndex, rootIndex);
|
2016-10-09 01:41:35 +08:00
|
|
|
this.heapSubtree(leftIndex, lastChild);
|
|
|
|
} else if (right < root) {
|
2016-10-09 01:42:37 +08:00
|
|
|
this.swap(rightIndex, rootIndex);
|
2016-10-09 01:41:35 +08:00
|
|
|
this.heapSubtree(rightIndex, lastChild);
|
|
|
|
}
|
|
|
|
} else if (hasLeftChild) { // if no right, but has left
|
|
|
|
int left = this.heap[leftIndex];
|
|
|
|
if (left < root) {
|
2016-10-09 01:42:37 +08:00
|
|
|
this.swap(leftIndex, rootIndex);
|
2016-10-09 01:41:35 +08:00
|
|
|
this.heapSubtree(leftIndex, lastChild);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Makes heap with {@code root} as root.
|
|
|
|
*
|
|
|
|
* @param root
|
|
|
|
* index of root of heap
|
|
|
|
*/
|
|
|
|
private void makeMinHeap(int root) {
|
2016-10-09 01:42:37 +08:00
|
|
|
int leftIndex = root * 2 + 1;
|
|
|
|
int rightIndex = root * 2 + 2;
|
2016-10-09 01:41:35 +08:00
|
|
|
boolean hasLeftChild = leftIndex < this.heap.length;
|
|
|
|
boolean hasRightChild = rightIndex < this.heap.length;
|
|
|
|
if (hasRightChild) { //if has left and right
|
|
|
|
this.makeMinHeap(leftIndex);
|
|
|
|
this.makeMinHeap(rightIndex);
|
|
|
|
this.heapSubtree(root, this.heap.length - 1);
|
|
|
|
} else if (hasLeftChild) {
|
|
|
|
this.heapSubtree(root, this.heap.length - 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets the root of this.heap.
|
|
|
|
*
|
|
|
|
* @return root of this.heap
|
|
|
|
*/
|
|
|
|
private int getRoot() {
|
|
|
|
this.swap(0, this.size - 1);
|
|
|
|
this.size--;
|
|
|
|
this.heapSubtree(0, this.size - 1);
|
|
|
|
return this.heap[this.size]; // return old root
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sorts this.heap with heap sort; displays ordered elements to console.
|
|
|
|
*
|
|
|
|
* @return {@code sorted} array of sorted elements
|
|
|
|
*/
|
|
|
|
public final int[] sort() {
|
|
|
|
this.makeMinHeap(0); // make min heap using index 0 as root.
|
|
|
|
int[] sorted = new int[this.size];
|
|
|
|
int index = 0;
|
|
|
|
while (this.size > 0) {
|
|
|
|
int min = this.getRoot();
|
|
|
|
sorted[index] = min;
|
|
|
|
index++;
|
|
|
|
}
|
|
|
|
return sorted;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets input to sort.
|
|
|
|
*
|
|
|
|
* @return unsorted array of integers to sort
|
|
|
|
*/
|
|
|
|
public static int[] getInput() {
|
|
|
|
final int numElements = 6;
|
|
|
|
int[] unsorted = new int[numElements];
|
|
|
|
Scanner input = new Scanner(System.in);
|
|
|
|
System.out.println("Enter any 6 Numbers for Unsorted Array : ");
|
|
|
|
for (int i = 0; i < numElements; i++) {
|
|
|
|
unsorted[i] = input.nextInt();
|
|
|
|
}
|
|
|
|
input.close();
|
|
|
|
return unsorted;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Prints elements in heap.
|
|
|
|
*
|
|
|
|
* @param heap
|
|
|
|
* array representing heap
|
|
|
|
*/
|
|
|
|
public static void printData(int[] heap) {
|
|
|
|
System.out.println("Sorted Elements:");
|
|
|
|
for (int i = 0; i < heap.length; i++) {
|
|
|
|
System.out.print(" " + heap[i] + " ");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Main method.
|
|
|
|
*
|
|
|
|
* @param args
|
|
|
|
* the command line arguments
|
|
|
|
*/
|
|
|
|
public static void main(String[] args) {
|
|
|
|
int[] heap = getInput();
|
|
|
|
HeapSort data = new HeapSort(heap);
|
|
|
|
int[] sorted = data.sort();
|
|
|
|
printData(sorted);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|