// 求前K大的数
public class TopK {
static List<Integer> res = new ArrayList<Integer>();
//第一种:基于小顶堆
public static void heapSelect(int[] a, int k) {
int n = a.length;
for (int i = (k-2)/2; i >= 0; i--)
sink(a, i, k-1);
for (int i = k; i < n; i++) {
if (a[i] > a[0]) {
exch(a, 0, i);
sink(a, 0, k-1);
}
}
for (int i = 0; i < k; i++)
res.add(a[i]);
}
// 前k大,用小顶堆
private static void sink(int[] a, int k, int n) {
while (2 * k + 1 <= n) {
int j = 2 * k + 1;
if (j < n && a[j] > a[j+1]) j++;
if (a[k] <= a[j]) break;
exch(a, k, j);
k = j;
}
}
// 第二种:基于快排
public static void quickSelect(int[] a, int k) {
select(a, k, 0, a.length-1);
for (int i = 0; i < k; i++)
res.add(a[i]);
}
private static void select(int[] a, int k, int lo, int hi) {
if (hi <= lo) return;
int j = partition(a, lo, hi);
if (j-lo+1 == k) return;
else if (j-lo+1 > k) select(a, k, lo, j-1);
else select(a, k-(j-lo+1), j+1, hi);
}
//从大到小 排序
private static int partition(int[] a, int lo, int hi) {
int i = lo, j = hi+1;
int v = a[lo];
while (true) {
while (a[++i] > v)
if (i == hi) break;
while (a[--j] < v)
if (j == lo) break;
if (i >= j) break;
exch(a, i, j);
}
exch(a, lo, j);
return j;
}
private static void exch(int[] a, int i, int j) {
int tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
public static void main(String[] args) {
int[] a = {5,3,7,1,9,4,3};
quickSelect(a, 4);
for (int i : res)
System.out.print(i + "\t");
}
}
TopK
猜你喜欢
转载自blog.csdn.net/weixin_39590058/article/details/88717452
今日推荐
周排行