Skip to content

Commit bded78f

Browse files
authored
refactor: BFPRT (#5445)
refactor: adding javadocs and tests for BFPRT
1 parent fa22317 commit bded78f

File tree

2 files changed

+111
-45
lines changed

2 files changed

+111
-45
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,32 @@
11
package com.thealgorithms.others;
22

3-
import java.util.Arrays;
4-
53
/**
6-
* BFPRT algorithm.
4+
* The BFPRT (Median of Medians) algorithm implementation.
5+
* It provides a way to find the k-th smallest element in an unsorted array
6+
* with an optimal worst-case time complexity of O(n).
7+
* This algorithm is used to find the k smallest numbers in an array.
78
*/
89
public final class BFPRT {
910
private BFPRT() {
1011
}
1112

13+
/**
14+
* Returns the k smallest elements from the array using the BFPRT algorithm.
15+
*
16+
* @param arr the input array
17+
* @param k the number of smallest elements to return
18+
* @return an array containing the k smallest elements, or null if k is invalid
19+
*/
1220
public static int[] getMinKNumsByBFPRT(int[] arr, int k) {
1321
if (k < 1 || k > arr.length) {
1422
return null;
1523
}
1624
int minKth = getMinKthByBFPRT(arr, k);
1725
int[] res = new int[k];
1826
int index = 0;
19-
for (int i = 0; i < arr.length; i++) {
20-
if (arr[i] < minKth) {
21-
res[index++] = arr[i];
27+
for (int value : arr) {
28+
if (value < minKth) {
29+
res[index++] = value;
2230
}
2331
}
2432
for (; index != res.length; index++) {
@@ -27,17 +35,39 @@ public static int[] getMinKNumsByBFPRT(int[] arr, int k) {
2735
return res;
2836
}
2937

38+
/**
39+
* Returns the k-th smallest element from the array using the BFPRT algorithm.
40+
*
41+
* @param arr the input array
42+
* @param k the rank of the smallest element to find
43+
* @return the k-th smallest element
44+
*/
3045
public static int getMinKthByBFPRT(int[] arr, int k) {
3146
int[] copyArr = copyArray(arr);
3247
return bfprt(copyArr, 0, copyArr.length - 1, k - 1);
3348
}
3449

50+
/**
51+
* Creates a copy of the input array.
52+
*
53+
* @param arr the input array
54+
* @return a copy of the array
55+
*/
3556
public static int[] copyArray(int[] arr) {
3657
int[] copyArr = new int[arr.length];
3758
System.arraycopy(arr, 0, copyArr, 0, arr.length);
3859
return copyArr;
3960
}
4061

62+
/**
63+
* BFPRT recursive method to find the k-th smallest element.
64+
*
65+
* @param arr the input array
66+
* @param begin the starting index
67+
* @param end the ending index
68+
* @param i the index of the desired smallest element
69+
* @return the k-th smallest element
70+
*/
4171
public static int bfprt(int[] arr, int begin, int end, int i) {
4272
if (begin == end) {
4373
return arr[begin];
@@ -54,12 +84,12 @@ public static int bfprt(int[] arr, int begin, int end, int i) {
5484
}
5585

5686
/**
57-
* wikipedia: https://en.wikipedia.org/wiki/Median_of_medians .
87+
* Finds the median of medians as the pivot element.
5888
*
59-
* @param arr an array.
60-
* @param begin begin num.
61-
* @param end end num.
62-
* @return median of medians.
89+
* @param arr the input array
90+
* @param begin the starting index
91+
* @param end the ending index
92+
* @return the median of medians
6393
*/
6494
public static int medianOfMedians(int[] arr, int begin, int end) {
6595
int num = end - begin + 1;
@@ -71,12 +101,15 @@ public static int medianOfMedians(int[] arr, int begin, int end) {
71101
return bfprt(mArr, 0, mArr.length - 1, mArr.length / 2);
72102
}
73103

74-
public static void swap(int[] arr, int i, int j) {
75-
int swap = arr[i];
76-
arr[i] = arr[j];
77-
arr[j] = swap;
78-
}
79-
104+
/**
105+
* Partitions the array around a pivot.
106+
*
107+
* @param arr the input array
108+
* @param begin the starting index
109+
* @param end the ending index
110+
* @param num the pivot element
111+
* @return the range where the pivot is located
112+
*/
80113
public static int[] partition(int[] arr, int begin, int end, int num) {
81114
int small = begin - 1;
82115
int cur = begin;
@@ -90,19 +123,31 @@ public static int[] partition(int[] arr, int begin, int end, int num) {
90123
cur++;
91124
}
92125
}
93-
int[] pivotRange = new int[2];
94-
pivotRange[0] = small + 1;
95-
pivotRange[1] = big - 1;
96-
return pivotRange;
126+
return new int[] {small + 1, big - 1};
97127
}
98128

129+
/**
130+
* Finds the median of the elements between the specified range.
131+
*
132+
* @param arr the input array
133+
* @param begin the starting index
134+
* @param end the ending index
135+
* @return the median of the specified range
136+
*/
99137
public static int getMedian(int[] arr, int begin, int end) {
100138
insertionSort(arr, begin, end);
101139
int sum = begin + end;
102140
int mid = sum / 2 + (sum % 2);
103141
return arr[mid];
104142
}
105143

144+
/**
145+
* Sorts a portion of the array using insertion sort.
146+
*
147+
* @param arr the input array
148+
* @param begin the starting index
149+
* @param end the ending index
150+
*/
106151
public static void insertionSort(int[] arr, int begin, int end) {
107152
if (arr == null || arr.length < 2) {
108153
return;
@@ -118,29 +163,16 @@ public static void insertionSort(int[] arr, int begin, int end) {
118163
}
119164
}
120165

121-
public static void main(String[] args) {
122-
int[] arr = {
123-
11,
124-
9,
125-
1,
126-
3,
127-
9,
128-
2,
129-
2,
130-
5,
131-
6,
132-
5,
133-
3,
134-
5,
135-
9,
136-
7,
137-
2,
138-
5,
139-
5,
140-
1,
141-
9,
142-
};
143-
int[] minK = getMinKNumsByBFPRT(arr, 5);
144-
System.out.println(Arrays.toString(minK));
166+
/**
167+
* Swaps two elements in an array.
168+
*
169+
* @param arr the input array
170+
* @param i the index of the first element
171+
* @param j the index of the second element
172+
*/
173+
public static void swap(int[] arr, int i, int j) {
174+
int temp = arr[i];
175+
arr[i] = arr[j];
176+
arr[j] = temp;
145177
}
146178
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package com.thealgorithms.others;
2+
3+
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
4+
import static org.junit.jupiter.api.Assertions.assertEquals;
5+
6+
import java.util.stream.Stream;
7+
import org.junit.jupiter.params.ParameterizedTest;
8+
import org.junit.jupiter.params.provider.Arguments;
9+
import org.junit.jupiter.params.provider.MethodSource;
10+
11+
class BFPRTTest {
12+
13+
@ParameterizedTest
14+
@MethodSource("minKNumsTestData")
15+
void testGetMinKNumsByBFPRT(int[] arr, int k, int[] expected) {
16+
int[] result = BFPRT.getMinKNumsByBFPRT(arr, k);
17+
assertArrayEquals(expected, result);
18+
}
19+
20+
private static Stream<Arguments> minKNumsTestData() {
21+
return Stream.of(Arguments.of(new int[] {11, 9, 1, 3, 9, 2, 2, 5, 6, 5, 3, 5, 9, 7, 2, 5, 5, 1, 9}, 5, new int[] {1, 1, 2, 2, 2}), Arguments.of(new int[] {3, 2, 1}, 2, new int[] {1, 2}), Arguments.of(new int[] {7, 5, 9, 1, 3, 8, 2, 4, 6}, 3, new int[] {1, 2, 3}));
22+
}
23+
24+
@ParameterizedTest
25+
@MethodSource("minKthTestData")
26+
void testGetMinKthByBFPRT(int[] arr, int k, int expected) {
27+
int result = BFPRT.getMinKthByBFPRT(arr, k);
28+
assertEquals(expected, result);
29+
}
30+
31+
private static Stream<Arguments> minKthTestData() {
32+
return Stream.of(Arguments.of(new int[] {3, 2, 1}, 2, 2), Arguments.of(new int[] {7, 5, 9, 1, 3, 8, 2, 4, 6}, 3, 3), Arguments.of(new int[] {5, 8, 6, 3, 2, 7, 1, 4}, 4, 4));
33+
}
34+
}

0 commit comments

Comments
 (0)