Skip to content

Commit 2837585

Browse files
authored
refactor: IntrospectiveSort (#5316)
1 parent 66bfaff commit 2837585

File tree

2 files changed

+93
-93
lines changed

2 files changed

+93
-93
lines changed

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

+89-34
Original file line numberDiff line numberDiff line change
@@ -9,76 +9,131 @@ public class IntrospectiveSort implements SortAlgorithm {
99

1010
private static final int INSERTION_SORT_THRESHOLD = 16;
1111

12+
/**
13+
* Sorts the given array using Introspective Sort, which combines quicksort, heapsort, and insertion sort.
14+
*
15+
* @param array The array to be sorted
16+
* @param <T> The type of elements in the array, which must be comparable
17+
* @return The sorted array
18+
*/
1219
@Override
13-
public <T extends Comparable<T>> T[] sort(T[] a) {
14-
int n = a.length;
15-
introSort(a, 0, n - 1, 2 * (int) (Math.log(n) / Math.log(2)));
16-
return a;
20+
public <T extends Comparable<T>> T[] sort(T[] array) {
21+
if (array == null || array.length <= 1) {
22+
return array;
23+
}
24+
final int depth = 2 * (int) (Math.log(array.length) / Math.log(2));
25+
introspectiveSort(array, 0, array.length - 1, depth);
26+
return array;
1727
}
1828

19-
private static <T extends Comparable<T>> void introSort(T[] a, int low, int high, int depth) {
29+
/**
30+
* Performs introspective sort on the specified subarray.
31+
*
32+
* @param array The array to be sorted
33+
* @param low The starting index of the subarray
34+
* @param high The ending index of the subarray
35+
* @param depth The current depth of recursion
36+
* @param <T> The type of elements in the array, which must be comparable
37+
*/
38+
private static <T extends Comparable<T>> void introspectiveSort(T[] array, final int low, int high, final int depth) {
2039
while (high - low > INSERTION_SORT_THRESHOLD) {
2140
if (depth == 0) {
22-
heapSort(a, low, high);
41+
heapSort(array, low, high);
2342
return;
2443
}
25-
int pivotIndex = partition(a, low, high);
26-
introSort(a, pivotIndex + 1, high, depth - 1);
44+
final int pivotIndex = partition(array, low, high);
45+
introspectiveSort(array, pivotIndex + 1, high, depth - 1);
2746
high = pivotIndex - 1;
2847
}
29-
insertionSort(a, low, high);
48+
insertionSort(array, low, high);
3049
}
3150

32-
private static <T extends Comparable<T>> int partition(T[] a, int low, int high) {
33-
int pivotIndex = low + (int) (Math.random() * (high - low + 1));
34-
SortUtils.swap(a, pivotIndex, high);
35-
T pivot = a[high];
51+
/**
52+
* Partitions the array around a pivot.
53+
*
54+
* @param array The array to be partitioned
55+
* @param low The starting index of the subarray
56+
* @param high The ending index of the subarray
57+
* @param <T> The type of elements in the array, which must be comparable
58+
* @return The index of the pivot
59+
*/
60+
private static <T extends Comparable<T>> int partition(T[] array, final int low, final int high) {
61+
final int pivotIndex = low + (int) (Math.random() * (high - low + 1));
62+
SortUtils.swap(array, pivotIndex, high);
63+
final T pivot = array[high];
3664
int i = low - 1;
37-
for (int j = low; j <= high - 1; j++) {
38-
if (a[j].compareTo(pivot) <= 0) {
65+
for (int j = low; j < high; j++) {
66+
if (array[j].compareTo(pivot) <= 0) {
3967
i++;
40-
SortUtils.swap(a, i, j);
68+
SortUtils.swap(array, i, j);
4169
}
4270
}
43-
SortUtils.swap(a, i + 1, high);
71+
SortUtils.swap(array, i + 1, high);
4472
return i + 1;
4573
}
4674

47-
private static <T extends Comparable<T>> void insertionSort(T[] a, int low, int high) {
75+
/**
76+
* Sorts a subarray using insertion sort.
77+
*
78+
* @param array The array to be sorted
79+
* @param low The starting index of the subarray
80+
* @param high The ending index of the subarray
81+
* @param <T> The type of elements in the array, which must be comparable
82+
*/
83+
private static <T extends Comparable<T>> void insertionSort(T[] array, final int low, final int high) {
4884
for (int i = low + 1; i <= high; i++) {
49-
T key = a[i];
85+
final T key = array[i];
5086
int j = i - 1;
51-
while (j >= low && a[j].compareTo(key) > 0) {
52-
a[j + 1] = a[j];
87+
while (j >= low && array[j].compareTo(key) > 0) {
88+
array[j + 1] = array[j];
5389
j--;
5490
}
55-
a[j + 1] = key;
91+
array[j + 1] = key;
5692
}
5793
}
5894

59-
private static <T extends Comparable<T>> void heapSort(T[] a, int low, int high) {
60-
for (int i = (high + low - 1) / 2; i >= low; i--) {
61-
heapify(a, i, high - low + 1, low);
95+
/**
96+
* Sorts a subarray using heapsort.
97+
*
98+
* @param array The array to be sorted
99+
* @param low The starting index of the subarray
100+
* @param high The ending index of the subarray
101+
* @param <T> The type of elements in the array, which must be comparable
102+
*/
103+
private static <T extends Comparable<T>> void heapSort(T[] array, final int low, final int high) {
104+
final int n = high - low + 1;
105+
for (int i = (n / 2) - 1; i >= 0; i--) {
106+
heapify(array, i, n, low);
62107
}
63108
for (int i = high; i > low; i--) {
64-
SortUtils.swap(a, low, i);
65-
heapify(a, low, i - low, low);
109+
SortUtils.swap(array, low, i);
110+
heapify(array, 0, i - low, low);
66111
}
67112
}
68113

69-
private static <T extends Comparable<T>> void heapify(T[] a, int i, int n, int low) {
70-
int left = 2 * i - low + 1;
71-
int right = 2 * i - low + 2;
114+
/**
115+
* Maintains the heap property for a subarray.
116+
*
117+
* @param array The array to be heapified
118+
* @param i The index to be heapified
119+
* @param n The size of the heap
120+
* @param low The starting index of the subarray
121+
* @param <T> The type of elements in the array, which must be comparable
122+
*/
123+
private static <T extends Comparable<T>> void heapify(T[] array, final int i, final int n, final int low) {
124+
final int left = 2 * i + 1;
125+
final int right = 2 * i + 2;
72126
int largest = i;
73-
if (left < n && a[left].compareTo(a[largest]) > 0) {
127+
128+
if (left < n && array[low + left].compareTo(array[low + largest]) > 0) {
74129
largest = left;
75130
}
76-
if (right < n && a[right].compareTo(a[largest]) > 0) {
131+
if (right < n && array[low + right].compareTo(array[low + largest]) > 0) {
77132
largest = right;
78133
}
79134
if (largest != i) {
80-
SortUtils.swap(a, i, largest);
81-
heapify(a, largest, n, low);
135+
SortUtils.swap(array, low + i, low + largest);
136+
heapify(array, largest, n, low);
82137
}
83138
}
84139
}
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,8 @@
11
package com.thealgorithms.sorts;
22

3-
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
4-
import static org.junit.jupiter.api.Assertions.assertThrows;
5-
6-
import org.junit.jupiter.api.Test;
7-
8-
public class IntrospectiveSortTest {
9-
@Test
10-
// valid test case
11-
public void strandSortNonDuplicateTest() {
12-
Integer[] expectedArray = {1, 2, 3, 4, 5};
13-
Integer[] actualList = new IntrospectiveSort().sort(expectedArray);
14-
assertArrayEquals(expectedArray, actualList);
15-
}
16-
17-
@Test
18-
// valid test case
19-
public void strandSortDuplicateTest() {
20-
Integer[] expectedArray = {2, 2, 2, 5, 7};
21-
Integer[] actualList = new IntrospectiveSort().sort(expectedArray);
22-
assertArrayEquals(expectedArray, actualList);
23-
}
24-
25-
@Test
26-
// valid test case
27-
public void strandSortEmptyTest() {
28-
Integer[] expectedArray = {};
29-
Integer[] actualList = new IntrospectiveSort().sort(expectedArray);
30-
assertArrayEquals(expectedArray, actualList);
31-
}
32-
33-
@Test
34-
// valid test case
35-
public void strandSortNullTest() {
36-
Integer[] expectedArray = null;
37-
assertThrows(NullPointerException.class, () -> { new IntrospectiveSort().sort(expectedArray); });
38-
}
39-
40-
@Test
41-
// valid test case
42-
public void strandSortNegativeTest() {
43-
Integer[] expectedArray = {-1, -2, -3, -4, -5};
44-
Integer[] actualList = new IntrospectiveSort().sort(expectedArray);
45-
assertArrayEquals(expectedArray, actualList);
46-
}
47-
48-
@Test
49-
// valid test case
50-
public void strandSortNegativeAndPositiveTest() {
51-
Integer[] expectedArray = {-1, -2, -3, 4, 5};
52-
Integer[] actualList = new IntrospectiveSort().sort(expectedArray);
53-
assertArrayEquals(expectedArray, actualList);
54-
}
55-
56-
@Test
57-
// valid test case
58-
public void allSameTest() {
59-
Integer[] expectedArray = {1, 1, 1, 1, 1};
60-
Integer[] actualList = new IntrospectiveSort().sort(expectedArray);
61-
assertArrayEquals(expectedArray, actualList);
3+
public class IntrospectiveSortTest extends SortingAlgorithmTest {
4+
@Override
5+
SortAlgorithm getSortAlgorithm() {
6+
return new IntrospectiveSort();
627
}
638
}

0 commit comments

Comments
 (0)