Skip to content

Commit 8ef69bc

Browse files
alxkmalxvil02
authored
Improving BitonicSort (#5244)
* Improving BitonicSort * Moving max method to SortingUtils * Adding Javadoc to merge method * Fix for test and code improvements * Improving code readability * Renaming method parameters --------- Co-authored-by: alx <[email protected]> Co-authored-by: vil02 <[email protected]>
1 parent 15d2e70 commit 8ef69bc

File tree

2 files changed

+99
-58
lines changed

2 files changed

+99
-58
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,79 +1,112 @@
11
package com.thealgorithms.sorts;
22

3-
/* Java program for Bitonic Sort. Note that this program
4-
works only when size of input is a power of 2. */
5-
public class BitonicSort {
6-
7-
/* The parameter dir indicates the sorting direction,
8-
ASCENDING or DESCENDING; if (a[i] > a[j]) agrees
9-
with the direction, then a[i] and a[j] are
10-
interchanged. */
11-
void compAndSwap(int[] a, int i, int j, int dir) {
12-
if ((a[i] > a[j] && dir == 1) || (a[i] < a[j] && dir == 0)) {
13-
// Swapping elements
14-
int temp = a[i];
15-
a[i] = a[j];
16-
a[j] = temp;
17-
}
3+
import java.util.Arrays;
4+
import java.util.function.BiPredicate;
5+
6+
/**
7+
* BitonicSort class implements the SortAlgorithm interface using the bitonic sort technique.
8+
*/
9+
public class BitonicSort implements SortAlgorithm {
10+
private enum Direction {
11+
DESCENDING,
12+
ASCENDING,
1813
}
1914

20-
/* It recursively sorts a bitonic sequence in ascending
21-
order, if dir = 1, and in descending order otherwise
22-
(means dir=0). The sequence to be sorted starts at
23-
index position low, the parameter cnt is the number
24-
of elements to be sorted.*/
25-
void bitonicMerge(int[] a, int low, int cnt, int dir) {
26-
if (cnt > 1) {
27-
int k = cnt / 2;
28-
for (int i = low; i < low + k; i++) {
29-
compAndSwap(a, i, i + k, dir);
30-
}
31-
bitonicMerge(a, low, k, dir);
32-
bitonicMerge(a, low + k, k, dir);
15+
/**
16+
* Sorts the given array using the Bitonic Sort algorithm.
17+
*
18+
* @param <T> the type of elements in the array, which must implement the Comparable interface
19+
* @param array the array to be sorted
20+
* @return the sorted array
21+
*/
22+
@Override
23+
public <T extends Comparable<T>> T[] sort(T[] array) {
24+
if (array.length == 0) {
25+
return array;
3326
}
27+
28+
final int paddedSize = nextPowerOfTwo(array.length);
29+
T[] paddedArray = Arrays.copyOf(array, paddedSize);
30+
31+
// Fill the padded part with a maximum value
32+
final T maxValue = max(array);
33+
Arrays.fill(paddedArray, array.length, paddedSize, maxValue);
34+
35+
bitonicSort(paddedArray, 0, paddedSize, Direction.ASCENDING);
36+
return Arrays.copyOf(paddedArray, array.length);
3437
}
3538

36-
/* This funcion first produces a bitonic sequence by
37-
recursively sorting its two halves in opposite sorting
38-
orders, and then calls bitonicMerge to make them in
39-
the same order */
40-
void bitonicSort(int[] a, int low, int cnt, int dir) {
39+
private <T extends Comparable<T>> void bitonicSort(final T[] array, final int low, final int cnt, final Direction direction) {
4140
if (cnt > 1) {
42-
int k = cnt / 2;
41+
final int k = cnt / 2;
4342

44-
// sort in ascending order since dir here is 1
45-
bitonicSort(a, low, k, 1);
43+
// Sort first half in ascending order
44+
bitonicSort(array, low, k, Direction.ASCENDING);
4645

47-
// sort in descending order since dir here is 0
48-
bitonicSort(a, low + k, k, 0);
46+
// Sort second half in descending order
47+
bitonicSort(array, low + k, cnt - k, Direction.DESCENDING);
4948

50-
// Will merge whole sequence in ascending order
51-
// since dir=1.
52-
bitonicMerge(a, low, cnt, dir);
49+
// Merge the whole sequence in ascending order
50+
bitonicMerge(array, low, cnt, direction);
5351
}
5452
}
5553

56-
/*Caller of bitonicSort for sorting the entire array
57-
of length N in ASCENDING order */
58-
void sort(int[] a, int n, int up) {
59-
bitonicSort(a, 0, n, up);
54+
/**
55+
* Merges the bitonic sequence in the specified direction.
56+
*
57+
* @param <T> the type of elements in the array, which must be Comparable
58+
* @param array the array containing the bitonic sequence to be merged
59+
* @param low the starting index of the sequence to be merged
60+
* @param cnt the number of elements in the sequence to be merged
61+
* @param direction the direction of sorting
62+
*/
63+
private <T extends Comparable<T>> void bitonicMerge(T[] array, int low, int cnt, Direction direction) {
64+
if (cnt > 1) {
65+
final int k = cnt / 2;
66+
67+
final BiPredicate<T, T> areSorted = (direction == Direction.ASCENDING) ? (a, b) -> a.compareTo(b) < 0 : (a, b) -> a.compareTo(b) > 0;
68+
for (int i = low; i < low + k; i++) {
69+
if (!areSorted.test(array[i], array[i + k])) {
70+
SortUtils.swap(array, i, i + k);
71+
}
72+
}
73+
74+
bitonicMerge(array, low, k, direction);
75+
bitonicMerge(array, low + k, cnt - k, direction);
76+
}
6077
}
6178

62-
/* A utility function to print array of size n */
63-
static void printArray(int[] arr) {
64-
int n = arr.length;
65-
for (int i = 0; i < n; ++i) {
66-
System.out.print(arr[i] + " ");
79+
/**
80+
* Finds the next power of two greater than or equal to the given number.
81+
*
82+
* @param n the number
83+
* @return the next power of two
84+
*/
85+
private static int nextPowerOfTwo(int n) {
86+
int count = 0;
87+
88+
// First n in the below condition is for the case where n is 0
89+
if ((n & (n - 1)) == 0) {
90+
return n;
91+
}
92+
93+
while (n != 0) {
94+
n >>= 1;
95+
count += 1;
6796
}
68-
System.out.println();
97+
98+
return 1 << count;
6999
}
70100

71-
public static void main(String[] args) {
72-
int[] a = {3, 7, 4, 8, 6, 2, 1, 5};
73-
int up = 1;
74-
BitonicSort ob = new BitonicSort();
75-
ob.sort(a, a.length, up);
76-
System.out.println("\nSorted array");
77-
printArray(a);
101+
/**
102+
* Finds the maximum element in the given array.
103+
*
104+
* @param <T> the type of elements in the array, which must implement the Comparable interface
105+
* @param array the array to be searched
106+
* @return the maximum element in the array
107+
* @throws IllegalArgumentException if the array is null or empty
108+
*/
109+
private static <T extends Comparable<T>> T max(final T[] array) {
110+
return Arrays.stream(array).max(Comparable::compareTo).orElseThrow();
78111
}
79112
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package com.thealgorithms.sorts;
2+
3+
public class BitonicSortTest extends SortingAlgorithmTest {
4+
@Override
5+
SortAlgorithm getSortAlgorithm() {
6+
return new BitonicSort();
7+
}
8+
}

0 commit comments

Comments
 (0)