Skip to content

Commit 71c91a1

Browse files
authored
Add BFPRT algorithm (TheAlgorithms#2590)
1 parent fb626e0 commit 71c91a1

1 file changed

Lines changed: 129 additions & 0 deletions

File tree

Others/BFPRT.java

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
package Others;
2+
3+
import java.util.Arrays;
4+
5+
/**
6+
* BFPRT algorithm.
7+
*/
8+
public class BFPRT {
9+
10+
public static int[] getMinKNumsByBFPRT(int[] arr, int k) {
11+
if (k < 1 || k > arr.length) {
12+
return null;
13+
}
14+
int minKth = getMinKthByBFPRT(arr, k);
15+
int[] res = new int[k];
16+
int index = 0;
17+
for (int i = 0; i < arr.length; i++) {
18+
if (arr[i] < minKth) {
19+
res[index++] = arr[i];
20+
}
21+
}
22+
for (; index != res.length; index++) {
23+
res[index] = minKth;
24+
}
25+
return res;
26+
}
27+
28+
public static int getMinKthByBFPRT(int[] arr, int k) {
29+
int[] copyArr = copyArray(arr);
30+
return bfprt(copyArr, 0, copyArr.length - 1, k - 1);
31+
}
32+
33+
public static int[] copyArray(int[]arr) {
34+
int[] copyArr = new int[arr.length];
35+
for(int i = 0; i < arr.length; i++) {
36+
copyArr[i] = arr[i];
37+
}
38+
return copyArr;
39+
}
40+
41+
public static int bfprt(int[] arr, int begin, int end, int i) {
42+
if (begin == end) {
43+
return arr[begin];
44+
}
45+
int pivot = medianOfMedians(arr, begin, end);
46+
int[] pivotRange = partition(arr, begin, end, pivot);
47+
if (i >= pivotRange[0] && i <= pivotRange[1]) {
48+
return arr[i];
49+
} else if (i < pivotRange[0]) {
50+
return bfprt(arr, begin, pivotRange[0] - 1, i);
51+
} else {
52+
return bfprt(arr, pivotRange[1] + 1, end, i);
53+
}
54+
}
55+
56+
/**
57+
* wikipedia: https://en.wikipedia.org/wiki/Median_of_medians .
58+
* @param arr an array.
59+
* @param begin begin num.
60+
* @param end end num.
61+
* @return median of medians.
62+
*/
63+
public static int medianOfMedians(int[] arr, int begin, int end) {
64+
int num = end - begin + 1;
65+
int offset = num % 5 == 0 ? 0 : 1;
66+
int[] mArr = new int[num / 5 + offset];
67+
for (int i = 0;i < mArr.length;i++) {
68+
mArr[i] = getMedian(arr, begin + i * 5, Math.min(end, begin + i * 5 + 4));
69+
}
70+
return bfprt(mArr, 0, mArr.length - 1, mArr.length / 2);
71+
}
72+
73+
public static void swap(int[]arr, int i, int j) {
74+
int swap = arr[i];
75+
arr[i] = arr[j];
76+
arr[j] = swap;
77+
}
78+
79+
public static int[] partition(int[] arr,int begin,int end,int num)
80+
{
81+
int small=begin-1;
82+
int cur=begin;
83+
int big=end+1;
84+
while(cur!=big)
85+
{
86+
if (arr[cur]<num)
87+
{
88+
swap(arr,++small,cur++);
89+
}else if (arr[cur]>num)
90+
{
91+
swap(arr,--big,cur);
92+
} else {
93+
cur++;
94+
}
95+
}
96+
int[] pivotRange=new int[2];
97+
pivotRange[0]=small+1;
98+
pivotRange[1]=big-1;
99+
return pivotRange;
100+
}
101+
102+
public static int getMedian(int[] arr, int begin, int end) {
103+
insertionSort(arr, begin, end);
104+
int sum = begin + end;
105+
int mid = sum / 2 + (sum % 2);
106+
return arr[mid];
107+
}
108+
109+
public static void insertionSort(int[] arr, int begin, int end) {
110+
if (arr == null || arr.length < 2) {
111+
return;
112+
}
113+
for (int i = begin + 1;i != end + 1;i++) {
114+
for (int j = i;j != begin;j--) {
115+
if (arr[j - 1] > arr[j]) {
116+
swap(arr, j - 1, j);
117+
} else {
118+
break;
119+
}
120+
}
121+
}
122+
}
123+
124+
public static void main(String[] args) {
125+
int[] arr = { 11, 9, 1, 3, 9, 2, 2, 5, 6, 5, 3, 5, 9, 7, 2, 5, 5, 1, 9 };
126+
int[] minK = getMinKNumsByBFPRT(arr,5);
127+
System.out.println(Arrays.toString(minK));
128+
}
129+
}

0 commit comments

Comments
 (0)