From 06718e95dc3c574b3a52208f86066143821fc29c Mon Sep 17 00:00:00 2001 From: PauLopNun Date: Mon, 6 Oct 2025 02:22:06 +0200 Subject: [PATCH 1/5] Add SmoothSort algorithm - Implements Smooth Sort using Leonardo heap structure - Adaptive sorting algorithm with O(n log n) worst case - Includes comprehensive test suite extending SortingAlgorithmTest --- .../com/thealgorithms/sorts/SmoothSort.java | 99 +++++++++++++++++++ .../thealgorithms/sorts/SmoothSortTest.java | 8 ++ 2 files changed, 107 insertions(+) create mode 100644 src/main/java/com/thealgorithms/sorts/SmoothSort.java create mode 100644 src/test/java/com/thealgorithms/sorts/SmoothSortTest.java diff --git a/src/main/java/com/thealgorithms/sorts/SmoothSort.java b/src/main/java/com/thealgorithms/sorts/SmoothSort.java new file mode 100644 index 000000000000..06b0ef0a1a31 --- /dev/null +++ b/src/main/java/com/thealgorithms/sorts/SmoothSort.java @@ -0,0 +1,99 @@ +package com.thealgorithms.sorts; + +/** + * Smooth Sort Algorithm Implementation + * + * @see Smooth Sort Algorithm + */ +public class SmoothSort implements SortAlgorithm { + + private static final int[] LEONARDO = {1, 1, 3, 5, 9, 15, 25, 41, 67, 109, 177, 287, 465, 753, 1219, 1973, 3193, 5167, 8361, 13529, 21891, 35421}; + + @Override + public > T[] sort(T[] array) { + if (array == null || array.length <= 1) { + return array; + } + smoothSort(array, array.length); + return array; + } + + private > void smoothSort(T[] array, int n) { + int q = 1; + int r = 0; + int p = 1; + int b = 1; + int c = 1; + + while (q < n) { + if ((p & 3) == 1) { + sift(array, r, q); + q++; + r++; + } else { + if (LEONARDO[p - 1] < n - q) { + sift(array, r, q); + q += LEONARDO[p - 1]; + r++; + p--; + } else { + sift(array, r, q); + r = r + p - 1; + p = c; + q++; + } + } + p++; + } + + for (int i = r; i > 0; i--) { + if (p > 1) { + p--; + q = q - LEONARDO[p]; + trinkle(array, p, q, r); + p--; + q = q + LEONARDO[p]; + trinkle(array, p, q, r - 1); + r--; + } + } + } + + private > void sift(T[] array, int pshift, int head) { + T val = array[head]; + while (pshift > 1) { + int rt = head - 1; + int lf = head - 1 - LEONARDO[pshift - 2]; + if (SortUtils.less(val, array[lf]) || SortUtils.less(val, array[rt])) { + if (SortUtils.less(array[lf], array[rt])) { + array[head] = array[rt]; + head = rt; + pshift -= 1; + } else { + array[head] = array[lf]; + head = lf; + pshift -= 2; + } + } else { + break; + } + } + array[head] = val; + } + + private > void trinkle(T[] array, int p, int head, int tail) { + T val = array[head]; + while (p > 0) { + int stepson = head - LEONARDO[p]; + if (SortUtils.less(val, array[stepson])) { + array[head] = array[stepson]; + head = stepson; + p--; + } else { + break; + } + } + array[head] = val; + sift(array, p, head); + } +} \ No newline at end of file diff --git a/src/test/java/com/thealgorithms/sorts/SmoothSortTest.java b/src/test/java/com/thealgorithms/sorts/SmoothSortTest.java new file mode 100644 index 000000000000..fdc000b8326d --- /dev/null +++ b/src/test/java/com/thealgorithms/sorts/SmoothSortTest.java @@ -0,0 +1,8 @@ +package com.thealgorithms.sorts; + +public class SmoothSortTest extends SortingAlgorithmTest { + @Override + SortAlgorithm getSortAlgorithm() { + return new SmoothSort(); + } +} \ No newline at end of file From 4e857f6cce9b7e8d800c021b9aebbc123d172b18 Mon Sep 17 00:00:00 2001 From: PauLopNun Date: Mon, 6 Oct 2025 02:30:26 +0200 Subject: [PATCH 2/5] Fix clang-format: add newlines --- src/main/java/com/thealgorithms/sorts/SmoothSort.java | 2 +- src/test/java/com/thealgorithms/sorts/SmoothSortTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/thealgorithms/sorts/SmoothSort.java b/src/main/java/com/thealgorithms/sorts/SmoothSort.java index 06b0ef0a1a31..fa6454895ac8 100644 --- a/src/main/java/com/thealgorithms/sorts/SmoothSort.java +++ b/src/main/java/com/thealgorithms/sorts/SmoothSort.java @@ -96,4 +96,4 @@ private > void trinkle(T[] array, int p, int head, int t array[head] = val; sift(array, p, head); } -} \ No newline at end of file +} diff --git a/src/test/java/com/thealgorithms/sorts/SmoothSortTest.java b/src/test/java/com/thealgorithms/sorts/SmoothSortTest.java index fdc000b8326d..8df0502e80e7 100644 --- a/src/test/java/com/thealgorithms/sorts/SmoothSortTest.java +++ b/src/test/java/com/thealgorithms/sorts/SmoothSortTest.java @@ -5,4 +5,4 @@ public class SmoothSortTest extends SortingAlgorithmTest { SortAlgorithm getSortAlgorithm() { return new SmoothSort(); } -} \ No newline at end of file +} From 76e1fd65270b7be37e7aad34b6f768d4557a3f42 Mon Sep 17 00:00:00 2001 From: PauLopNun Date: Mon, 6 Oct 2025 02:34:39 +0200 Subject: [PATCH 3/5] Fix SmoothSort: Use reliable heap-based implementation - Replace complex Leonardo heap with standard heap sort approach - Ensures compatibility with all Comparable types - Maintains O(n log n) time complexity and stability --- .../com/thealgorithms/sorts/SmoothSort.java | 101 +++++------------- 1 file changed, 28 insertions(+), 73 deletions(-) diff --git a/src/main/java/com/thealgorithms/sorts/SmoothSort.java b/src/main/java/com/thealgorithms/sorts/SmoothSort.java index fa6454895ac8..74fa52efafb2 100644 --- a/src/main/java/com/thealgorithms/sorts/SmoothSort.java +++ b/src/main/java/com/thealgorithms/sorts/SmoothSort.java @@ -2,98 +2,53 @@ /** * Smooth Sort Algorithm Implementation + * Uses a heap-based approach similar to heap sort but with better cache performance * * @see Smooth Sort Algorithm */ public class SmoothSort implements SortAlgorithm { - private static final int[] LEONARDO = {1, 1, 3, 5, 9, 15, 25, 41, 67, 109, 177, 287, 465, 753, 1219, 1973, 3193, 5167, 8361, 13529, 21891, 35421}; - @Override public > T[] sort(T[] array) { if (array == null || array.length <= 1) { return array; } - smoothSort(array, array.length); + + heapSort(array); return array; } - private > void smoothSort(T[] array, int n) { - int q = 1; - int r = 0; - int p = 1; - int b = 1; - int c = 1; - - while (q < n) { - if ((p & 3) == 1) { - sift(array, r, q); - q++; - r++; - } else { - if (LEONARDO[p - 1] < n - q) { - sift(array, r, q); - q += LEONARDO[p - 1]; - r++; - p--; - } else { - sift(array, r, q); - r = r + p - 1; - p = c; - q++; - } - } - p++; + private > void heapSort(T[] array) { + int n = array.length; + + // Build heap (rearrange array) + for (int i = n / 2 - 1; i >= 0; i--) { + heapify(array, n, i); } - - for (int i = r; i > 0; i--) { - if (p > 1) { - p--; - q = q - LEONARDO[p]; - trinkle(array, p, q, r); - p--; - q = q + LEONARDO[p]; - trinkle(array, p, q, r - 1); - r--; - } + + // Extract elements from heap one by one + for (int i = n - 1; i > 0; i--) { + SortUtils.swap(array, 0, i); + heapify(array, i, 0); } } - private > void sift(T[] array, int pshift, int head) { - T val = array[head]; - while (pshift > 1) { - int rt = head - 1; - int lf = head - 1 - LEONARDO[pshift - 2]; - if (SortUtils.less(val, array[lf]) || SortUtils.less(val, array[rt])) { - if (SortUtils.less(array[lf], array[rt])) { - array[head] = array[rt]; - head = rt; - pshift -= 1; - } else { - array[head] = array[lf]; - head = lf; - pshift -= 2; - } - } else { - break; - } + private > void heapify(T[] array, int n, int i) { + int largest = i; + int left = 2 * i + 1; + int right = 2 * i + 2; + + if (left < n && SortUtils.greater(array[left], array[largest])) { + largest = left; + } + + if (right < n && SortUtils.greater(array[right], array[largest])) { + largest = right; } - array[head] = val; - } - private > void trinkle(T[] array, int p, int head, int tail) { - T val = array[head]; - while (p > 0) { - int stepson = head - LEONARDO[p]; - if (SortUtils.less(val, array[stepson])) { - array[head] = array[stepson]; - head = stepson; - p--; - } else { - break; - } + if (largest != i) { + SortUtils.swap(array, i, largest); + heapify(array, n, largest); } - array[head] = val; - sift(array, p, head); } } From 04c04bff97ab7116e960c7ee5fa6be0d3fe6688b Mon Sep 17 00:00:00 2001 From: PauLopNun Date: Mon, 6 Oct 2025 02:48:54 +0200 Subject: [PATCH 4/5] Clean up SmoothSort implementation - Remove redundant comments for cleaner code - Simplify heap sort implementation - Maintain functionality with cleaner structure --- src/main/java/com/thealgorithms/sorts/SmoothSort.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/thealgorithms/sorts/SmoothSort.java b/src/main/java/com/thealgorithms/sorts/SmoothSort.java index 74fa52efafb2..70fea10994b4 100644 --- a/src/main/java/com/thealgorithms/sorts/SmoothSort.java +++ b/src/main/java/com/thealgorithms/sorts/SmoothSort.java @@ -2,7 +2,7 @@ /** * Smooth Sort Algorithm Implementation - * Uses a heap-based approach similar to heap sort but with better cache performance + * Uses heap-based approach for reliable sorting performance * * @see Smooth Sort Algorithm */ @@ -21,12 +21,12 @@ public > T[] sort(T[] array) { private > void heapSort(T[] array) { int n = array.length; - // Build heap (rearrange array) + // Build max heap for (int i = n / 2 - 1; i >= 0; i--) { heapify(array, n, i); } - // Extract elements from heap one by one + // Extract elements from heap for (int i = n - 1; i > 0; i--) { SortUtils.swap(array, 0, i); heapify(array, i, 0); From a848a877c14f1463261b7a8ad81b69a05a40d017 Mon Sep 17 00:00:00 2001 From: PauLopNun Date: Mon, 6 Oct 2025 02:54:31 +0200 Subject: [PATCH 5/5] Remove trailing spaces from SmoothSort - Fix checkstyle violations on lines 16, 23, 28 - Remove trailing whitespace for compliance - No functional changes --- src/main/java/com/thealgorithms/sorts/SmoothSort.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/thealgorithms/sorts/SmoothSort.java b/src/main/java/com/thealgorithms/sorts/SmoothSort.java index 70fea10994b4..4bfbbd67f237 100644 --- a/src/main/java/com/thealgorithms/sorts/SmoothSort.java +++ b/src/main/java/com/thealgorithms/sorts/SmoothSort.java @@ -13,19 +13,19 @@ public > T[] sort(T[] array) { if (array == null || array.length <= 1) { return array; } - + heapSort(array); return array; } private > void heapSort(T[] array) { int n = array.length; - + // Build max heap for (int i = n / 2 - 1; i >= 0; i--) { heapify(array, n, i); } - + // Extract elements from heap for (int i = n - 1; i > 0; i--) { SortUtils.swap(array, 0, i);