From 2679715bb25e140566e5b3d0ecddcf9ac63b46b4 Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Sun, 16 Feb 2025 16:40:56 +0530 Subject: [PATCH 1/2] Heapsort Implementation --- clients/build.gradle | 1 + .../clients/module8/HeapSortClient.java | 23 ++++++++ module8/build.gradle | 21 ++++++++ .../hithomelabs/princeton1/module8/Heap.java | 52 +++++++++++++++++++ .../princeton1/module8/HeapSort.java | 31 +++++++++++ .../princeton1/module8/HeapSortTest.java | 51 ++++++++++++++++++ settings.gradle | 1 + 7 files changed, 180 insertions(+) create mode 100644 clients/src/main/java/com/hithomelabs/clients/module8/HeapSortClient.java create mode 100644 module8/build.gradle create mode 100644 module8/src/main/java/com/hithomelabs/princeton1/module8/Heap.java create mode 100644 module8/src/main/java/com/hithomelabs/princeton1/module8/HeapSort.java create mode 100644 module8/src/test/java/com/hithomelabs/princeton1/module8/HeapSortTest.java 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' From 0f662bf89c5e106f915781fba33fa5535b6d3d20 Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Sun, 16 Feb 2025 17:05:10 +0530 Subject: [PATCH 2/2] Adding heap sort to practice --- .gitignore | 3 ++- .../hithomelabs/princeton1/module8/Heap.java | 19 +------------------ .../princeton1/module8/HeapSort.java | 16 ++++++---------- 3 files changed, 9 insertions(+), 29 deletions(-) diff --git a/.gitignore b/.gitignore index 4a305d7..cf74795 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ # Ignore Gradle project-specific cache directory .gradle - +# Igonre the .idea directory +.idea # Ignore Gradle build output directory build bin \ 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 index f5e5a65..b728767 100644 --- a/module8/src/main/java/com/hithomelabs/princeton1/module8/Heap.java +++ b/module8/src/main/java/com/hithomelabs/princeton1/module8/Heap.java @@ -11,29 +11,13 @@ 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 + * * Implement sink API to sink a node if it's sub-heap is not heap-order */ 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){ @@ -43,7 +27,6 @@ public class Heap{ } 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 index bb71d81..55d7b91 100644 --- a/module8/src/main/java/com/hithomelabs/princeton1/module8/HeapSort.java +++ b/module8/src/main/java/com/hithomelabs/princeton1/module8/HeapSort.java @@ -10,22 +10,18 @@ public class HeapSort extends AbstractCustomSorts { int N = arr.length; E[] heapArr = (E[]) new Object[N+1]; - // * * to simplify we copy original array from + // * * to simplify we copy original array and write it to the new array starting index 1 System.arraycopy(arr, 0, heapArr, 1, N); - // * * An array of size N holds a heap of size N-1 coreSortingLogic(heapArr, N); + // * * Re-copying the sorted array to the original System.arraycopy(heapArr, 1, arr, 0, N); } + /* + * * Implement the core sorting logic + * * P.S the provision of making the index 0 null for ease of use has already been done above + */ 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); - } } }