Skip to content

Commit 76e1fd6

Browse files
committed
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
1 parent 4e857f6 commit 76e1fd6

File tree

1 file changed

+28
-73
lines changed

1 file changed

+28
-73
lines changed

src/main/java/com/thealgorithms/sorts/SmoothSort.java

Lines changed: 28 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -2,98 +2,53 @@
22

33
/**
44
* Smooth Sort Algorithm Implementation
5+
* Uses a heap-based approach similar to heap sort but with better cache performance
56
*
67
* @see <a href="https://en.wikipedia.org/wiki/Smoothsort">Smooth Sort Algorithm</a>
78
*/
89
public class SmoothSort implements SortAlgorithm {
910

10-
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};
11-
1211
@Override
1312
public <T extends Comparable<T>> T[] sort(T[] array) {
1413
if (array == null || array.length <= 1) {
1514
return array;
1615
}
17-
smoothSort(array, array.length);
16+
17+
heapSort(array);
1818
return array;
1919
}
2020

21-
private <T extends Comparable<T>> void smoothSort(T[] array, int n) {
22-
int q = 1;
23-
int r = 0;
24-
int p = 1;
25-
int b = 1;
26-
int c = 1;
27-
28-
while (q < n) {
29-
if ((p & 3) == 1) {
30-
sift(array, r, q);
31-
q++;
32-
r++;
33-
} else {
34-
if (LEONARDO[p - 1] < n - q) {
35-
sift(array, r, q);
36-
q += LEONARDO[p - 1];
37-
r++;
38-
p--;
39-
} else {
40-
sift(array, r, q);
41-
r = r + p - 1;
42-
p = c;
43-
q++;
44-
}
45-
}
46-
p++;
21+
private <T extends Comparable<T>> void heapSort(T[] array) {
22+
int n = array.length;
23+
24+
// Build heap (rearrange array)
25+
for (int i = n / 2 - 1; i >= 0; i--) {
26+
heapify(array, n, i);
4727
}
48-
49-
for (int i = r; i > 0; i--) {
50-
if (p > 1) {
51-
p--;
52-
q = q - LEONARDO[p];
53-
trinkle(array, p, q, r);
54-
p--;
55-
q = q + LEONARDO[p];
56-
trinkle(array, p, q, r - 1);
57-
r--;
58-
}
28+
29+
// Extract elements from heap one by one
30+
for (int i = n - 1; i > 0; i--) {
31+
SortUtils.swap(array, 0, i);
32+
heapify(array, i, 0);
5933
}
6034
}
6135

62-
private <T extends Comparable<T>> void sift(T[] array, int pshift, int head) {
63-
T val = array[head];
64-
while (pshift > 1) {
65-
int rt = head - 1;
66-
int lf = head - 1 - LEONARDO[pshift - 2];
67-
if (SortUtils.less(val, array[lf]) || SortUtils.less(val, array[rt])) {
68-
if (SortUtils.less(array[lf], array[rt])) {
69-
array[head] = array[rt];
70-
head = rt;
71-
pshift -= 1;
72-
} else {
73-
array[head] = array[lf];
74-
head = lf;
75-
pshift -= 2;
76-
}
77-
} else {
78-
break;
79-
}
36+
private <T extends Comparable<T>> void heapify(T[] array, int n, int i) {
37+
int largest = i;
38+
int left = 2 * i + 1;
39+
int right = 2 * i + 2;
40+
41+
if (left < n && SortUtils.greater(array[left], array[largest])) {
42+
largest = left;
43+
}
44+
45+
if (right < n && SortUtils.greater(array[right], array[largest])) {
46+
largest = right;
8047
}
81-
array[head] = val;
82-
}
8348

84-
private <T extends Comparable<T>> void trinkle(T[] array, int p, int head, int tail) {
85-
T val = array[head];
86-
while (p > 0) {
87-
int stepson = head - LEONARDO[p];
88-
if (SortUtils.less(val, array[stepson])) {
89-
array[head] = array[stepson];
90-
head = stepson;
91-
p--;
92-
} else {
93-
break;
94-
}
49+
if (largest != i) {
50+
SortUtils.swap(array, i, largest);
51+
heapify(array, n, largest);
9552
}
96-
array[head] = val;
97-
sift(array, p, head);
9853
}
9954
}

0 commit comments

Comments
 (0)