快速选择算法,是一种能在大致O(N)的时间内选取数组中第k大或者k小的算法.其基本思路与快速排序算法类似,也是分治的思想.
可以用于解决找到第K大的数,或者第k小的数。
1 执行Partition算法(就是那个快排里将区间内所有数划分为小的一部分和大的一部分的过程)
2 判断第k大的数是在小的部分还是大的部分
3 递归,直到区间足够小,返回结果
package selectTest;
import javax.print.attribute.standard.Media;
public class qucikSelect {
private static int qucikselect(int[] a, int from, int to, int k) {
if(k>a.length) return -1;
int i = from, j = to, m = (i + j) / 2;
while (i <= j) {
while (a[i] < a[m])
i++;
while (a[j] > a[m])
j--;
if (i <= j) {
int tmp = a[i];
a[i] = a[j];
a[j] = tmp;
i++;
j--;
}
}
if (from < j && k <= j)
return qucikselect(a, from, j, k);
if (i < to && k <= i)
return qucikselect(a, i, to, k);
return a[k-1];
}
public static void main(String[] args) {
int[] test = { 1,2,3,5,5,4,6,7,8,9};
System.out.println(qucikselect(test, 0,test.length-1,1));
System.out.println();
for(int i=0;i<test.length;i++){
System.out.print(test[i]+"\t");
}
}
}
版本2
package selectTest;
import javax.print.attribute.standard.Media;
public class qucikSelect {
private static int qucikselect(int[] s, int l, int r, int k) {
if (k > s.length)
return -1;
if (l < r) {
int i = l, j = r, x = s[l]; // x是基准
while (i < j) {
while (i < j && s[j] >= x)
// 从右向左找第一个小于x的数
j--;
if (i < j)
s[i++] = s[j];
while (i < j && s[i] < x)
// 从左向右找第一个大于等于x的数
i++;
if (i < j)
s[j--] = s[i];
}
s[i] = x; // 把基准赋给s[i]
if (i < k-1)
return qucikselect(s, i + 1, r, k);
else if (i > k-1) {
return qucikselect(s, l, i - 1, k);
} else {
return s[i];
}
}
return -1;
}
public static void main(String[] args) {
int[] test = { 1,4,3,7};
System.out.println(qucikselect(test, 0, test.length - 1, 3));
System.out.println();
for (int i = 0; i < test.length; i++) {
System.out.print(test[i] + "\t");
}
}
}