package com.hithomelabs.princeton1.module5; import java.util.ArrayList; import java.util.Comparator; public class Shell implements MeasurableSort, MeasurableHelper { /* * * 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) { coreSortLogic(arr,null,null); } private void coreSortLogic(E[] arr, Comparator cmp, SortingMetaData 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, cmp, metaData); h = h / 3; } } private int hsort(E[] arr, int h, Comparator cmp, SortingMetaData metaData) { int N = arr.length; for(int i = h; i < N; i++){ int j = i; while(j >= h && MeasurableHelper.less(arr[j], arr[j-h], cmp, metaData)){ MeasurableHelper.exch(arr, j, j-h, metaData); j = j - h; } } 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){ int h = 1; h = hsort(arr, h, null, null); } @Override public void sort(E[] arr, Comparator cmp, SortingMetaData metaData) { if (metaData != null) metaData.startTime(); coreSortLogic(arr, cmp, metaData); if (metaData != null) metaData.endTime(); } @Override public void sort(E[] arr, Comparator cmp) { coreSortLogic(arr, cmp, null); } @Override public String toString() { return "Shell Sort"; } }