Add Heapsort algorithm
This commit is contained in:
parent
9a3ded6487
commit
f6cc3e2878
2 changed files with 114 additions and 0 deletions
|
@ -0,0 +1,83 @@
|
||||||
|
package com.wbrawner.algorithms.sorting;
|
||||||
|
|
||||||
|
import static com.wbrawner.algorithms.sorting.SortUtils.swap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Heap Sort algorithm works by first organizing the data in a heap and
|
||||||
|
* then sorting it.
|
||||||
|
*/
|
||||||
|
public class HeapSort {
|
||||||
|
/**
|
||||||
|
* Sort a given array of ints using the Heap Sort algorithm
|
||||||
|
*
|
||||||
|
* @param unsorted an unsorted array of ints
|
||||||
|
* @return a sorted array of ints
|
||||||
|
*/
|
||||||
|
public static int[] sort(int[] unsorted) {
|
||||||
|
// An empty array or array with only a single value can't be sorted
|
||||||
|
if (unsorted.length < 2) {
|
||||||
|
return unsorted;
|
||||||
|
}
|
||||||
|
|
||||||
|
buildMaxHeap(unsorted);
|
||||||
|
|
||||||
|
int end = unsorted.length - 1;
|
||||||
|
while (end > 0) {
|
||||||
|
swap(unsorted, end, 0);
|
||||||
|
end--;
|
||||||
|
siftDown(unsorted, 0, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
return unsorted;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static void buildMaxHeap(int[] unsorted) {
|
||||||
|
int startIndex = getParentIndex(unsorted.length - 1);
|
||||||
|
|
||||||
|
while (startIndex >= 0) {
|
||||||
|
siftDown(unsorted, startIndex, unsorted.length - 1);
|
||||||
|
startIndex--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static void siftDown(int[] array, int start, int end) {
|
||||||
|
int root = start;
|
||||||
|
int child;
|
||||||
|
while ((child = getLeftChild(root)) <= end) {
|
||||||
|
int swap = root;
|
||||||
|
|
||||||
|
if (array[swap] < array[child]) {
|
||||||
|
// If the left child is greater than the parent, they need to
|
||||||
|
// be swapped
|
||||||
|
swap = child;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (child + 1 <= end && array[swap] < array[child + 1]) {
|
||||||
|
// If there is a right child though and it is greater than
|
||||||
|
// the left child, then it should be the one to be swapped
|
||||||
|
swap = child + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (swap == root) {
|
||||||
|
// If the children are absent or less than the parent, then
|
||||||
|
// this node is fine and no swaps need to be made
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
swap(array, root, swap);
|
||||||
|
root = swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int getParentIndex(int index) {
|
||||||
|
return (int) Math.floor((index - 1) / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static int getLeftChild(int index) {
|
||||||
|
return index * 2 + 1;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
package com.wbrawner.algorithms.sorting;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.junit.runners.Parameterized;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertArrayEquals;
|
||||||
|
|
||||||
|
@RunWith(Parameterized.class)
|
||||||
|
public class ParameterizedHeapSortTest {
|
||||||
|
|
||||||
|
|
||||||
|
@Parameterized.Parameter(1)
|
||||||
|
public int[] sorted;
|
||||||
|
|
||||||
|
@Parameterized.Parameter()
|
||||||
|
public int[] unsorted;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void sortTest() {
|
||||||
|
assertArrayEquals(
|
||||||
|
sorted,
|
||||||
|
HeapSort.sort(unsorted)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Parameterized.Parameters
|
||||||
|
public static int[][][] getData() {
|
||||||
|
return SortData.get();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue