求数组中前k大的数据
思路:维护一个数据大小为k的小顶堆,循环遍历数组,如果比堆顶元素大,我们就把堆顶元素删除,并且将这个元素插入到堆中;如果比堆顶元素小,则不做处理,继续遍历数组。这样等数组中的数据都遍历完之后,堆中的数据就是前 K 大数据了。
public static int[] topK(int[] data, int k) {
//初始化top数据
int[] topK = new int[k];
for (int i = 0; i < k; i++) {
topK[i] = data[i];
}
smallHeapAdjust(topK);
for (int i = k; i < data.length; i++) {
//如果该数据比堆顶元素大,则替换堆顶元素。调整堆
if (data[i] > topK[0]) {
topK[0] = data[i];
smallHeapAdjust(topK);
}
}
return topK;
}
public static void smallHeapAdjust(int[] data) {
int temp = data[0];
int index = 0;
for (int i = index * 2 + 1; i < data.length; i = i * 2 + 1) {
if (i + 1 < data.length && data[i] > data[i + 1]) {
//左孩子节点大于右孩子节点,指向右孩子
i++;
}
//如果该结点比最小的孩子节点小,退出
if (temp < data[i]) {
break;
}
//将最小的孩子结点的值赋值给该结点
data[index] = data[i];
index = i;
}
data[index] = temp;
}