diff --git a/clients/src/main/java/com/hithomelabs/clients/module5/ShellClient.java b/clients/src/main/java/com/hithomelabs/clients/module5/ShellClient.java new file mode 100644 index 0000000..504eede --- /dev/null +++ b/clients/src/main/java/com/hithomelabs/clients/module5/ShellClient.java @@ -0,0 +1,29 @@ +package com.hithomelabs.clients.module5; + +import com.hithomelabs.princeton1.module5.Apple; +import com.hithomelabs.princeton1.module5.Shell; + +import java.util.Arrays; +import java.util.Random; + +public class ShellClient { + + public static void main(String[] args) { + + int size = 100; + Apple[] apples = new Apple[size]; + Shell shell = new Shell(); + + for (int i = 0; i < apples.length; i++) { + apples[i] = new Apple(new Random().nextInt(1000)); + } + Apple[] applesCopy = Arrays.copyOf(apples, size); + shell.sort(apples); + shell.insertionSort(applesCopy); + + //* * Sample output + for (int i = 0; i < apples.length; i++) + System.out.println(apples[i]); + } +} + diff --git a/module5/src/main/java/com/hithomelabs/princeton1/module5/Shell.java b/module5/src/main/java/com/hithomelabs/princeton1/module5/Shell.java new file mode 100644 index 0000000..97a08ff --- /dev/null +++ b/module5/src/main/java/com/hithomelabs/princeton1/module5/Shell.java @@ -0,0 +1,66 @@ +package com.hithomelabs.princeton1.module5; + +public class Shell extends AbstractCustomSorts { + + // * * sample metadata class to compare no. of sorts and compares, shell sort vs insertion sort + private class MetaData{ + + int compares; + int swaps; + } + +/* + * * We will be performing h sort + * * Suppose or function to determine subsequent values of h is: + * * h(i+1) = 3*h(i) + 1; h = 1, 4, 13, 40, 121, .... + * * h will never be perfectly divisible by 3; further dividing h[i]/3 will give h[i-1] + * * We want to h-sort using larges value of h smaller than N, followed by smaller values of h + * * If N = 100, we h-sort by 40, meaning every 40th element will be in order + * * Then we h-sort by 13, meaning every 40th and every 13th element will be in order and every 40th element will be in order + * * Finally, when h will come out as 1, it will be same as insertion sort, however by that time the array will almost be sorted + * * Insertion sort for an almost sorted array is linear time. + * * As a case study we implement both insertion sort and selection sort for an array of 1000 nos. + * * And check number of compares and no. of exchanges in each case + */ + @Override + public void sort(E[] arr) { + MetaData metaData = new MetaData(); + int N = arr.length; + int h = 1; + // * * Calculates the largest value of h greater than n + while (3 * h + 1 < N) { + h = 3 * h + 1; + } + while (h >= 1) { + h = hsort(arr, h, metaData); + h = h / 3; + } + System.out.println("Array sorted (shell sort) with " + metaData.compares + " compares and " + metaData.swaps + " swaps"); + } + + private int hsort(E[] arr, int h, MetaData metadata) { + int N = arr.length; + for(int i = h; i < N; i++){ + int j = i; + ++metadata.compares; + while(j >= h && less((Comparable) arr[j], arr[j-h])){ + ++metadata.swaps; + exch(arr, j, j-h); + j = j - h; + ++metadata.compares; + } + } + return h; + } + /* + ! sample implementation of insertion sort as h-sort of h = 1 + * Will just be comparing the number of saps taken across both implementations + */ + public void insertionSort(E[] arr){ + MetaData metaData = new MetaData(); + int h = 1; + h = hsort(arr, h, metaData); + System.out.println("Array sorted (insertion sort) with " + metaData.compares + " compares and " + metaData.swaps + " swaps"); + } + +} diff --git a/module5/src/test/java/com/hithomelabs/princeton1/module5/InsertionTest.java b/module5/src/test/java/com/hithomelabs/princeton1/module5/SortTest.java similarity index 100% rename from module5/src/test/java/com/hithomelabs/princeton1/module5/InsertionTest.java rename to module5/src/test/java/com/hithomelabs/princeton1/module5/SortTest.java