-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathKmin.java
More file actions
91 lines (76 loc) · 2.81 KB
/
Kmin.java
File metadata and controls
91 lines (76 loc) · 2.81 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
package algorithmtest;
import java.util.Arrays;
public class Kmin {
public static void main(String[] args) {
int[] A = { 8, 33, 17, 51, 57, 49, 35, 11, 25, 37, 14, 3, 2, 13, 52,
12, 6, 29, 32, 54, 5, 16, 22, 23, 7 };
int K = 18;
int theLastKMin = findTheLastKMinNum(A, 0, A.length - 1, K);
System.out.println("第" + K + "小的数是:" + theLastKMin);
}
/**
*
* 方法名: findTheLastKMinNum
* 方法作用: 分治法求第k小值
* 创建人:WENTAO Wan
* 创建时间:2016年4月4日 下午11:15:39
* @param @param A
* @param @param low
* @param @param high
* @param @param K
* @param @return
* 返回值类型: int
* @throws
*/
public static int findTheLastKMinNum(int[] A, int low, int high, int K) {
// 设置阈值
int p = high - low + 1;
if (p < 6) {
// 这里要注意新分配的空间 q+1造成干扰,不能直接Sort(A)
Arrays.sort(A, low, p);
return A[K - 1];
} else {
// 分为五段
int q = p / 5;
int remainder = p - q * 5;
// 每段排序并把中项存入mid
int[] mid = new int[q + 1];
for (int i = 0; i < q; i++) {
Arrays.sort(A, 5 * i, (i + 1) * 5);
mid[i] = A[i * 5 + 2]; // low
}
// 除不尽5之后的分为一段并找出中项存入mid
if (remainder > 0) {
Arrays.sort(A, 5 * q, 5 * q + remainder);
mid[q] = A[q * 5 + (remainder + 1) / 2 - 1];
}
// 中项集合的中项
int mm = findTheLastKMinNum(mid, 0, q - 1, (q + 1) / 2);
int[] A1 = new int[p];
int[] A2 = new int[p];
int[] A3 = new int[p];
int lenA1 = 0, lenA2 = 0, lenA3 = 0;
// 分别与中项比较,分为新的三段
for (int i = low; i <= high; i++) {
if (A[i] < mm) {
A1[lenA1++] = A[i];
} else if (A[i] == mm) {
A2[lenA2++] = A[i];
} else if (A[i] > mm) {
A3[lenA3++] = A[i];
}
}
// 将三段的长度与K比较判断K的位置并递归
int theLastKMin = 0;
if (lenA1 >= K) {
theLastKMin = findTheLastKMinNum(A1, 0, lenA1 - 1, K);
} else if (lenA2 + lenA1 < K) {
theLastKMin = findTheLastKMinNum(A3, 0, lenA3 - 1, K - lenA1
- lenA2);
} else if (lenA1 + lenA2 >= K) {
theLastKMin = mm;
}
return theLastKMin;
}
}
}