From 198fcbf0513c687b36bd6a84d7ecfbd0ee92ae36 Mon Sep 17 00:00:00 2001 From: wgroeneveld Date: Fri, 23 Mar 2018 15:29:08 +0100 Subject: [PATCH] heap sorting --- .../src/be/brainbaking/sorting/HeapSort.java | 90 +++++++++++++++++++ .../test/be/brainbaking/sorting/SortTest.java | 26 ++++++ 2 files changed, 116 insertions(+) create mode 100644 sorting/java/src/be/brainbaking/sorting/HeapSort.java diff --git a/sorting/java/src/be/brainbaking/sorting/HeapSort.java b/sorting/java/src/be/brainbaking/sorting/HeapSort.java new file mode 100644 index 0000000..bc2fe43 --- /dev/null +++ b/sorting/java/src/be/brainbaking/sorting/HeapSort.java @@ -0,0 +1,90 @@ +package be.brainbaking.sorting; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +public class HeapSort implements Sortable { + + private String asString(List list) { + return list.stream().map(i -> i.toString()).collect(Collectors.joining(", ")); + } + + /** + * heap-size[A] <- length[A] + * for i <- |length[A]/2| downto 1 + * do MAX-HEAPIFY(A, i) + */ + protected List buildMaxHeap(List list) { + System.out.println("to maxify: " + asString(list)); + List heapList = new ArrayList<>(list); + int halfIndex = (int)Math.floor(list.size() / 2); + + for(int i = halfIndex; i >= 1; i--) { + maxHeapify(heapList, i); + } + + System.out.println("maxified: " + asString(heapList)); + return heapList; + } + + private int leftIndex(int index) { + return index * 2; + } + + private int rightIndex(int index) { + return leftIndex(index) + 1; + } + + private int parentIndex(int index) { + return (int)Math.floor(index / 2); + } + + private void maxHeapify(List list, int oneBasedIndex) { + int lefti = leftIndex(oneBasedIndex); + int righti = rightIndex(oneBasedIndex); + int largesti = oneBasedIndex; + + if(lefti <= list.size() && list.get(lefti - 1) > list.get(oneBasedIndex - 1)) { + largesti = lefti; + } + if(righti <= list.size() && list.get(righti - 1) > list.get(largesti - 1)) { + largesti = righti; + } + + if(largesti != oneBasedIndex) { + swap(list, oneBasedIndex, largesti); + maxHeapify(list, largesti); + } + } + + private void swap(List list, int oneBasedA, int oneBasedB) { + int temp = list.get(oneBasedA - 1); + list.set(oneBasedA - 1, list.get(oneBasedB - 1)); + list.set(oneBasedB - 1, temp); + } + + /** + * BUILD-MAX-HEAP(A) + * for i <- length[A] downto 2 + * do exchange A[1] with A[i] + * heap-size[A] <- heap-size[A] - 1 + * MAX-HEAPIFY(A, 1) + */ + @Override + public List sort(List list) { + List heap = buildMaxHeap(list); + List sorted = new ArrayList<>(); + + for(int i = heap.size(); i >= 1; i--) { + // in plaats van te swappen met 1, i pitsen we het hoofd van de tree er af + // ik wil niet heap-size manipuleren en doorgeven + sorted.add(0, heap.get(0)); + heap.remove(0); + maxHeapify(heap, 1); + } + + System.out.println("sorted: " + asString(sorted)); + return sorted; + } +} diff --git a/sorting/java/test/be/brainbaking/sorting/SortTest.java b/sorting/java/test/be/brainbaking/sorting/SortTest.java index d5920e1..9a5d094 100644 --- a/sorting/java/test/be/brainbaking/sorting/SortTest.java +++ b/sorting/java/test/be/brainbaking/sorting/SortTest.java @@ -4,11 +4,37 @@ import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; public class SortTest { + @Test + public void heapSort_withBiggerHeap() { + HeapSort sort = new HeapSort(); + + List expetedSort = Arrays.asList(1, 2, 3, 4, 7, 8, 9, 10, 14, 16); + List actualSort = sort.sort(Arrays.asList(4, 1, 3, 2, 16, 9, 10, 14, 8, 7)); + + Assertions.assertArrayEquals(expetedSort.toArray(), actualSort.toArray()); + } + + @Test + public void heapSort_buildMaxHeap() { + HeapSort sort = new HeapSort(); + + List expectedHeap = Arrays.asList(16, 14, 10, 8, 7, 9, 3, 2, 4, 1); + List maxHeap = sort.buildMaxHeap(Arrays.asList(4, 1, 3, 2, 16, 9, 10, 14, 8, 7)); + + Assertions.assertArrayEquals(expectedHeap.toArray(), maxHeap.toArray()); + } + + @Test + public void heapSort() { + simpleTestCaseFor(new HeapSort()); + } + @Test public void insertionSort() { simpleTestCaseFor(new InsertionSort());