|
1 | 1 | package com.thealgorithms.sorts;
|
2 | 2 |
|
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; |
| 3 | +import java.util.Arrays; |
| 4 | + |
| 5 | +/** |
| 6 | + * BitonicSort class implements the SortAlgorithm interface using the bitonic sort technique. |
| 7 | + */ |
| 8 | +public class BitonicSort implements SortAlgorithm { |
| 9 | + |
| 10 | + /** |
| 11 | + * Sorts the given array using the Bitonic Sort algorithm. |
| 12 | + * |
| 13 | + * @param <T> the type of elements in the array, which must implement the Comparable interface |
| 14 | + * @param arr the array to be sorted |
| 15 | + * @return the sorted array |
| 16 | + */ |
| 17 | + @Override |
| 18 | + public <T extends Comparable<T>> T[] sort(T[] arr) { |
| 19 | + if (arr == null || arr.length == 0) { |
| 20 | + return arr; |
17 | 21 | }
|
| 22 | + |
| 23 | + int n = arr.length; |
| 24 | + int paddedSize = nextPowerOfTwo(n); |
| 25 | + T[] paddedArray = Arrays.copyOf(arr, paddedSize); |
| 26 | + |
| 27 | + // Fill the padded part with a maximum value |
| 28 | + T maxValue = findMax(arr); |
| 29 | + Arrays.fill(paddedArray, n, paddedSize, maxValue); |
| 30 | + |
| 31 | + bitonicSort(paddedArray, 0, paddedSize, true); |
| 32 | + |
| 33 | + return Arrays.copyOf(paddedArray, n); |
18 | 34 | }
|
19 | 35 |
|
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) { |
| 36 | + private <T extends Comparable<T>> void bitonicSort(T[] arr, int low, int cnt, boolean dir) { |
26 | 37 | if (cnt > 1) {
|
27 | 38 | 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); |
| 39 | + |
| 40 | + // Sort first half in ascending order |
| 41 | + bitonicSort(arr, low, k, true); |
| 42 | + |
| 43 | + // Sort second half in descending order |
| 44 | + bitonicSort(arr, low + k, cnt - k, false); |
| 45 | + |
| 46 | + // Merge the whole sequence in ascending order |
| 47 | + bitonicMerge(arr, low, cnt, dir); |
33 | 48 | }
|
34 | 49 | }
|
35 | 50 |
|
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) { |
| 51 | + private <T extends Comparable<T>> void bitonicMerge(T[] arr, int low, int cnt, boolean dir) { |
41 | 52 | if (cnt > 1) {
|
42 | 53 | int k = cnt / 2;
|
43 | 54 |
|
44 |
| - // sort in ascending order since dir here is 1 |
45 |
| - bitonicSort(a, low, k, 1); |
46 |
| - |
47 |
| - // sort in descending order since dir here is 0 |
48 |
| - bitonicSort(a, low + k, k, 0); |
| 55 | + for (int i = low; i < low + k; i++) { |
| 56 | + if (dir == (arr[i].compareTo(arr[i + k]) > 0)) { |
| 57 | + SortUtils.swap(arr, i, i + k); |
| 58 | + } |
| 59 | + } |
49 | 60 |
|
50 |
| - // Will merge whole sequence in ascending order |
51 |
| - // since dir=1. |
52 |
| - bitonicMerge(a, low, cnt, dir); |
| 61 | + bitonicMerge(arr, low, k, dir); |
| 62 | + bitonicMerge(arr, low + k, cnt - k, dir); |
53 | 63 | }
|
54 | 64 | }
|
55 | 65 |
|
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); |
60 |
| - } |
| 66 | + /** |
| 67 | + * Finds the maximum element in the given array. |
| 68 | + * |
| 69 | + * @param <T> the type of elements in the array, which must implement the Comparable interface |
| 70 | + * @param array the array to be searched |
| 71 | + * @return the maximum element in the array |
| 72 | + * @throws IllegalArgumentException if the array is null or empty |
| 73 | + */ |
| 74 | + public static <T extends Comparable<T>> T findMax(T[] array) { |
| 75 | + if (array == null || array.length == 0) { |
| 76 | + throw new IllegalArgumentException("Array must not be null or empty"); |
| 77 | + } |
61 | 78 |
|
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 | + T max = array[0]; |
| 80 | + for (T element : array) { |
| 81 | + if (element.compareTo(max) > 0) { |
| 82 | + max = element; |
| 83 | + } |
67 | 84 | }
|
68 |
| - System.out.println(); |
| 85 | + return max; |
69 | 86 | }
|
70 | 87 |
|
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); |
| 88 | + /** |
| 89 | + * Finds the next power of two greater than or equal to the given number. |
| 90 | + * |
| 91 | + * @param n the number |
| 92 | + * @return the next power of two |
| 93 | + */ |
| 94 | + private static int nextPowerOfTwo(int n) { |
| 95 | + int count = 0; |
| 96 | + |
| 97 | + // First n in the below condition is for the case where n is 0 |
| 98 | + if ((n & (n - 1)) == 0) { |
| 99 | + return n; |
| 100 | + } |
| 101 | + |
| 102 | + while (n != 0) { |
| 103 | + n >>= 1; |
| 104 | + count += 1; |
| 105 | + } |
| 106 | + |
| 107 | + return 1 << count; |
78 | 108 | }
|
79 | 109 | }
|
0 commit comments