From 5113101e5dd4eb2d74a8c9f5e15b73773b974bb5 Mon Sep 17 00:00:00 2001 From: Alex Klymenko Date: Fri, 26 Jul 2024 09:55:11 +0300 Subject: [PATCH] refactor: cleanup `ShellSort` (#5302) --- .../com/thealgorithms/sorts/ShellSort.java | 69 ++++++++++++------- .../thealgorithms/sorts/ShellSortTest.java | 66 ++---------------- 2 files changed, 50 insertions(+), 85 deletions(-) diff --git a/src/main/java/com/thealgorithms/sorts/ShellSort.java b/src/main/java/com/thealgorithms/sorts/ShellSort.java index 37a50e855698..d12b181e65a2 100644 --- a/src/main/java/com/thealgorithms/sorts/ShellSort.java +++ b/src/main/java/com/thealgorithms/sorts/ShellSort.java @@ -11,36 +11,59 @@ public class ShellSort implements SortAlgorithm { */ @Override public > T[] sort(T[] array) { - int length = array.length; - int gap = 1; - - /* Calculate gap for optimization purpose */ - while (gap < length / 3) { - gap = 3 * gap + 1; + if (array.length == 0) { + return array; } - for (; gap > 0; gap /= 3) { - for (int i = gap; i < length; i++) { - int j; - T temp = array[i]; - for (j = i; j >= gap && SortUtils.less(temp, array[j - gap]); j -= gap) { - array[j] = array[j - gap]; - } - array[j] = temp; - } + int gap = calculateInitialGap(array.length); + + while (gap > 0) { + performGapInsertionSort(array, gap); + gap = calculateNextGap(gap); } + return array; } - /* Driver Code */ - public static void main(String[] args) { - Integer[] toSort = {4, 23, 6, 78, 1, 54, 231, 9, 12}; + /** + * Calculates the initial gap value using the Knuth sequence. + * + * @param length the length of the array. + * @return the initial gap value. + */ + private int calculateInitialGap(final int length) { + int gap = 1; + while (gap < length / 3) { + gap = 3 * gap + 1; + } + return gap; + } + + /** + * Calculates the next gap value. + * + * @param currentGap the current gap value. + * @return the next gap value. + */ + private int calculateNextGap(final int currentGap) { + return currentGap / 3; + } - ShellSort sort = new ShellSort(); - sort.sort(toSort); - for (int i = 0; i < toSort.length - 1; ++i) { - assert toSort[i] <= toSort[i + 1]; + /** + * Performs an insertion sort for the specified gap value. + * + * @param array the array to be sorted. + * @param gap the current gap value. + * @param the type of elements in the array. + */ + private > void performGapInsertionSort(final T[] array, final int gap) { + for (int i = gap; i < array.length; i++) { + T temp = array[i]; + int j; + for (j = i; j >= gap && SortUtils.less(temp, array[j - gap]); j -= gap) { + array[j] = array[j - gap]; + } + array[j] = temp; } - SortUtils.print(toSort); } } diff --git a/src/test/java/com/thealgorithms/sorts/ShellSortTest.java b/src/test/java/com/thealgorithms/sorts/ShellSortTest.java index 73be91b397bd..b41f2c2e863b 100644 --- a/src/test/java/com/thealgorithms/sorts/ShellSortTest.java +++ b/src/test/java/com/thealgorithms/sorts/ShellSortTest.java @@ -1,66 +1,8 @@ package com.thealgorithms.sorts; -import static org.junit.jupiter.api.Assertions.assertArrayEquals; - -import org.junit.jupiter.api.Test; - -public class ShellSortTest { - - private ShellSort shellSort = new ShellSort(); - - @Test - public void shellSortEmptyArray() { - Integer[] inputArray = {}; - Integer[] outputArray = shellSort.sort(inputArray); - Integer[] expectedOutput = {}; - assertArrayEquals(outputArray, expectedOutput); - } - - @Test - public void shellSortSingleIntegerArray() { - Integer[] inputArray = {4}; - Integer[] outputArray = shellSort.sort(inputArray); - Integer[] expectedOutput = {4}; - assertArrayEquals(outputArray, expectedOutput); - } - - @Test - public void shellSortSingleStringArray() { - String[] inputArray = {"s"}; - String[] outputArray = shellSort.sort(inputArray); - String[] expectedOutput = {"s"}; - assertArrayEquals(outputArray, expectedOutput); - } - - @Test - public void shellSortNonDuplicateIntegerArray() { - Integer[] inputArray = {6, -1, 99, 27, -15, 23, -36}; - Integer[] outputArray = shellSort.sort(inputArray); - Integer[] expectedOutput = {-36, -15, -1, 6, 23, 27, 99}; - assertArrayEquals(outputArray, expectedOutput); - } - - @Test - public void shellSortDuplicateIntegerArray() { - Integer[] inputArray = {6, -1, 27, -15, 23, 27, -36, 23}; - Integer[] outputArray = shellSort.sort(inputArray); - Integer[] expectedOutput = {-36, -15, -1, 6, 23, 23, 27, 27}; - assertArrayEquals(outputArray, expectedOutput); - } - - @Test - public void shellSortNonDuplicateStringArray() { - String[] inputArray = {"s", "b", "k", "a", "d", "c", "h"}; - String[] outputArray = shellSort.sort(inputArray); - String[] expectedOutput = {"a", "b", "c", "d", "h", "k", "s"}; - assertArrayEquals(outputArray, expectedOutput); - } - - @Test - public void shellSortDuplicateStringArray() { - String[] inputArray = {"s", "b", "d", "a", "d", "c", "h", "b"}; - String[] outputArray = shellSort.sort(inputArray); - String[] expectedOutput = {"a", "b", "b", "c", "d", "d", "h", "s"}; - assertArrayEquals(outputArray, expectedOutput); +public class ShellSortTest extends SortingAlgorithmTest { + @Override + SortAlgorithm getSortAlgorithm() { + return new ShellSort(); } }