diff --git a/clients/build.gradle b/clients/build.gradle index d80e4c6..8e4f6b7 100644 --- a/clients/build.gradle +++ b/clients/build.gradle @@ -16,6 +16,7 @@ dependencies { implementation project(':module5') implementation project(':module6') implementation project(':module7') + implementation project(':module8') implementation project(':common') testImplementation project(':common') } diff --git a/clients/src/main/java/com/hithomelabs/clients/module8/HeapSortClient.java b/clients/src/main/java/com/hithomelabs/clients/module8/HeapSortClient.java new file mode 100644 index 0000000..4534500 --- /dev/null +++ b/clients/src/main/java/com/hithomelabs/clients/module8/HeapSortClient.java @@ -0,0 +1,23 @@ +package com.hithomelabs.clients.module8; + +import com.hithomelabs.princeton1.common.Apple; +import com.hithomelabs.princeton1.module8.HeapSort; + +import java.util.Random; + +public class HeapSortClient { + + public static void main(String[] args) { + int size = 10; + Apple[] apples = new Apple[size]; + HeapSort heap = new HeapSort(); + + for (int i = 0; i < apples.length; i++) { + apples[i] = new Apple(new Random().nextInt(10)); + } + heap.sort(apples); + for (int i = 0; i < apples.length; i++) + System.out.println(apples[i]); + } + +} diff --git a/module8/build.gradle b/module8/build.gradle new file mode 100644 index 0000000..9a03430 --- /dev/null +++ b/module8/build.gradle @@ -0,0 +1,21 @@ +plugins { + id 'java' +} + +group = 'com.hithomelabs.princeton1.module8' +version = 'unspecified' + +repositories { + mavenCentral() +} + +dependencies { + testImplementation platform('org.junit:junit-bom:5.10.0') + testImplementation 'org.junit.jupiter:junit-jupiter' + implementation project(':module5') + testImplementation project(':common') +} + +test { + useJUnitPlatform() +} \ No newline at end of file diff --git a/module8/src/main/java/com/hithomelabs/princeton1/module8/Heap.java b/module8/src/main/java/com/hithomelabs/princeton1/module8/Heap.java new file mode 100644 index 0000000..f5e5a65 --- /dev/null +++ b/module8/src/main/java/com/hithomelabs/princeton1/module8/Heap.java @@ -0,0 +1,52 @@ +package com.hithomelabs.princeton1.module8; + +/* + * * Designing Heap as a wrapper class with static methods that perform sink and swim operations on underlying comparable[] array + * * Heap does not have any instance variables, instance variables shall be housed by, the implementation using heaps, like priority queues and heap sort + */ + +import com.hithomelabs.princeton1.module5.AbstractCustomSorts; + +public class Heap{ + + /* + * * Sink Node T with to it's appropriate place in a Heap of size N, if it's children exist and are greater + */ + public static void sink(T[] arr, int root, int N){ + // * Check if at least one child exists + while(2 * root <= N){ + int j = 2 * root; + // * Check if the right child exists and is larger than the left child, if yes swap right and left child + if(j+1 <= N){ + if (less(arr[j], arr[j+1])) j++; + } + if (!less(arr[root], arr[j])) break; + exch(arr, root, j); + // * The root node has now sunken low, call sink recursively with new node to check if it sinks further + root = j; + } + } + + // * * Swim if element is not root, and parent is lesser than node + public static > void swim(T[] arr, int node, int N){ + while(node > 1){ + if(! less(arr[node/2],arr[node])) break; + exch(arr, node, node/2); + node = node/2; + } + } + + private static void exch(T[] arr, int i, int j){ + T temp = arr[i]; + arr[i] = arr[j]; + arr[j] = temp; + } + + private static boolean less(T v, T w){ + + if(((Comparable)v).compareTo(w) < 1 ) return true; + else return false; + } + + +} diff --git a/module8/src/main/java/com/hithomelabs/princeton1/module8/HeapSort.java b/module8/src/main/java/com/hithomelabs/princeton1/module8/HeapSort.java new file mode 100644 index 0000000..bb71d81 --- /dev/null +++ b/module8/src/main/java/com/hithomelabs/princeton1/module8/HeapSort.java @@ -0,0 +1,31 @@ +package com.hithomelabs.princeton1.module8; + +import com.hithomelabs.princeton1.module5.AbstractCustomSorts; + + +public class HeapSort extends AbstractCustomSorts { + + @Override + public void sort(E[] arr) { + int N = arr.length; + + E[] heapArr = (E[]) new Object[N+1]; + // * * to simplify we copy original array from + System.arraycopy(arr, 0, heapArr, 1, N); + + // * * An array of size N holds a heap of size N-1 + coreSortingLogic(heapArr, N); + System.arraycopy(heapArr, 1, arr, 0, N); + } + + private void coreSortingLogic(E[] arr, int N) { + // * * Converting array to max-heap an array in place + for (int i = N/2; i >= 1; i--) + Heap.sink(arr, i, N); + // * * After converting to max-heap, in every iteration remove the max element of the heap + while(N > 1){ + exch(arr, 1, N--); + Heap.sink(arr, 1, N); + } + } +} diff --git a/module8/src/test/java/com/hithomelabs/princeton1/module8/HeapSortTest.java b/module8/src/test/java/com/hithomelabs/princeton1/module8/HeapSortTest.java new file mode 100644 index 0000000..8f35154 --- /dev/null +++ b/module8/src/test/java/com/hithomelabs/princeton1/module8/HeapSortTest.java @@ -0,0 +1,51 @@ +package com.hithomelabs.princeton1.module8; + +import com.hithomelabs.princeton1.common.Apple; +import org.junit.jupiter.api.*; + +import java.util.ArrayList; +import java.util.Random; + +import static org.junit.jupiter.api.Assertions.*; + +class HeapSortTest { + + private HeapSort heap; + private ArrayList apples; + private Random random; + + @BeforeEach + void setUp() { + heap = new HeapSort(); + apples = new ArrayList(); + random = new Random(); + } + + @Test + @DisplayName("Sort a heap of a 100 random sized apples") + public void testSort(){ + for(int i = 0; i < 100; i++) + apples.add(new Apple(random.nextInt(1000))); + Apple[] arr = apples.toArray(new Apple[apples.size()]); + heap.sort(arr); + apples.sort(null); + Apple[] sorted = apples.toArray(new Apple[apples.size()]); + Assertions.assertArrayEquals(sorted, arr); + } + + @Test + @DisplayName("Sort 100 apples in descending order") + public void testSortBorder(){ + for(int i = 0; i < 100; i++) + apples.add(new Apple(100 - i)); + Apple[] arr = apples.toArray(new Apple[apples.size()]); + heap.sort(arr); + apples.sort(null); + Apple[] sorted = apples.toArray(new Apple[apples.size()]); + Assertions.assertArrayEquals(sorted, arr); + } + + @AfterEach + void tearDown() { + } +} \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index f9e40b6..2348850 100644 --- a/settings.gradle +++ b/settings.gradle @@ -17,4 +17,5 @@ include 'module5' include 'module6' include 'common' include 'module7' +include 'module8'