Refactored HeapSort

This commit is contained in:
nik 2018-04-10 11:16:28 +03:00
parent 9491b45a05
commit 18a5148576

View File

@ -1,6 +1,10 @@
package sort; package sort;
import java.util.Scanner; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static sort.SortUtils.*;
/** /**
* Heap Sort Algorithm * Heap Sort Algorithm
@ -9,168 +13,119 @@ import java.util.Scanner;
* @author Unknown * @author Unknown
* *
*/ */
public class HeapSort { public class HeapSort implements SortAlgorithm {
/** Array to store heap */
private int[] heap;
/** The size of the heap */
private int size;
/**
* Constructor
*
* @param heap array of unordered integers
*/
public HeapSort(int[] heap) {
this.setHeap(heap);
this.setSize(heap.length);
}
/** private static class Heap<T extends Comparable<T>> {
* Setter for variable size /** Array to store heap */
* private T[] heap;
* @param length new size
*/
private void setSize(int length) {
this.size = length;
}
/** /**
* Setter for variable heap * Constructor
* *
* @param heap array of unordered elements * @param heap array of unordered integers
*/ */
private void setHeap(int[] heap) { public Heap(T[] heap) {
this.heap = heap; this.heap = heap;
} }
/** /**
* Swaps index of first with second * Heapifies subtree from top as root to last as last child
* *
* @param first First index to switch * @param rootIndex index of root
* @param second Second index to switch * @param lastChild index of last child
*/ */
private void swap(int first, int second) { private void heapSubtree(int rootIndex, int lastChild) {
int temp = this.heap[first]; int leftIndex = rootIndex * 2 + 1;
this.heap[first] = this.heap[second]; int rightIndex = rootIndex * 2 + 2;
this.heap[second] = temp; T root = heap[rootIndex];
} if (rightIndex <= lastChild) { // if has right and left children
T left = heap[leftIndex];
/** T right = heap[rightIndex];
* Heapifies subtree from top as root to last as last child if (less(left, right) && less(left, root)) {
* swap(heap, leftIndex, rootIndex);
* @param rootIndex index of root heapSubtree(leftIndex, lastChild);
* @param lastChild index of last child } else if (less(right, root)) {
*/ swap(heap, rightIndex, rootIndex);
private void heapSubtree(int rootIndex, int lastChild) { heapSubtree(rightIndex, lastChild);
int leftIndex = rootIndex * 2 + 1; }
int rightIndex = rootIndex * 2 + 2; } else if (leftIndex <= lastChild) { // if no right child, but has left child
int root = this.heap[rootIndex]; T left = heap[leftIndex];
if (rightIndex <= lastChild) { // if has right and left children if (less(left, root)) {
int left = this.heap[leftIndex]; swap(heap, leftIndex, rootIndex);
int right = this.heap[rightIndex]; heapSubtree(leftIndex, lastChild);
if (left < right && left < root) { }
this.swap(leftIndex, rootIndex);
this.heapSubtree(leftIndex, lastChild);
} else if (right < root) {
this.swap(rightIndex, rootIndex);
this.heapSubtree(rightIndex, lastChild);
}
} else if (leftIndex <= lastChild) { // if no right child, but has left child
int left = this.heap[leftIndex];
if (left < root) {
this.swap(leftIndex, rootIndex);
this.heapSubtree(leftIndex, lastChild);
} }
} }
}
/**
* Makes heap with root as root /**
* * Makes heap with root as root
* @param root index of root of heap *
*/ * @param root index of root of heap
private void makeMinHeap(int root) { */
int leftIndex = root * 2 + 1; private void makeMinHeap(int root) {
int rightIndex = root * 2 + 2; int leftIndex = root * 2 + 1;
boolean hasLeftChild = leftIndex < this.heap.length; int rightIndex = root * 2 + 2;
boolean hasRightChild = rightIndex < this.heap.length; boolean hasLeftChild = leftIndex < heap.length;
if (hasRightChild) { //if has left and right boolean hasRightChild = rightIndex < heap.length;
this.makeMinHeap(leftIndex); if (hasRightChild) { //if has left and right
this.makeMinHeap(rightIndex); makeMinHeap(leftIndex);
this.heapSubtree(root, this.heap.length - 1); makeMinHeap(rightIndex);
} else if (hasLeftChild) { heapSubtree(root, heap.length - 1);
this.heapSubtree(root, this.heap.length - 1); } else if (hasLeftChild) {
heapSubtree(root, heap.length - 1);
}
} }
}
/** /**
* Gets the root of heap * Gets the root of heap
* *
* @return root of heap * @return root of heap
*/ */
private int getRoot() { private T getRoot(int size) {
this.swap(0, this.size - 1); swap(heap, 0, size);
this.size--; heapSubtree(0, size - 1);
this.heapSubtree(0, this.size - 1); return heap[size]; // return old root
return this.heap[this.size]; // return old root
}
/**
* Sorts heap with heap sort; displays ordered elements to console.
*
* @return 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++;
} }
}
@Override
public <T extends Comparable<T>> T[] sort(T[] unsorted) {
return sort(Arrays.asList(unsorted)).toArray(unsorted);
}
@Override
public <T extends Comparable<T>> List<T> sort(List<T> unsorted) {
int size = unsorted.size();
@SuppressWarnings("unchecked")
Heap<T> heap = new Heap<>(unsorted.toArray((T[]) new Comparable[unsorted.size()]));
heap.makeMinHeap(0); // make min heap using index 0 as root.
List<T> sorted = new ArrayList<>(size);
while (size > 0) {
T min = heap.getRoot(--size);
sorted.add(min);
}
return sorted; 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 * Main method
* *
* @param args the command line arguments * @param args the command line arguments
*/ */
public static void main(String[] args) { public static void main(String[] args) {
int[] heap = getInput(); Integer[] heap = {4, 23, 6, 78, 1, 54, 231, 9, 12};
HeapSort data = new HeapSort(heap); HeapSort heapSort = new HeapSort();
int[] sorted = data.sort(); print(heapSort.sort(heap));
printData(sorted);
} }
} }