TOP K堆就是堆,只是TOP K堆只用维护固定数量的元素,每次加进来新的,都要判断是否替换掉堆顶元素,如果需要,则删除堆顶元素,放入新元素,并重新构造堆。可以参考这里
package com.kingdee.gmis.common;
import java.util.Random;
/**
*
* @author hua_fan
*
*/
public class TopNHeap<T extends Comparable<? super T>> {
private int size;
private int maxSize;
private Object[] data = new Object[256];
public TopNHeap(T[] data) {
super();
this.initHeap(data);
}
public TopNHeap(int fixedSize) {
super();
assert fixedSize >= 1;
this.maxSize = fixedSize;
}
@SuppressWarnings("unchecked")
public void initHeap(T[] data) {
assert data.length >= 1;
if (this.data.length <= this.size) {
this.data = new Object[(int) (data.length * 1.5)];
}
this.maxSize = this.size = data.length;
System.arraycopy(data, 0, this.data, 0, this.size);
int startPos = this.getParentIndex(this.size - 1);
for (int i = startPos; i >= 0; i--) {
this.shiftdown(i);
}
}
@SuppressWarnings("unchecked")
public T getHeapTop() {
return (T) this.data[0];
}
/**
* 加元素到堆中,但是保持堆 的大小
*
* @param value
*/
public void addToHeap(T value) {
if (this.maxSize > this.size) {
this.data[this.size] = value;
this.shiftup(this.size++);
} else {
if (value.compareTo(this.getHeapTop()) > 0) {
this.data[0] = value;
this.shiftdown(0);
}
}
}
private void shiftup(int pos) {
int parentIdx = this.getParentIndex(pos);
while (pos != 0
&& this.getValue(pos).compareTo(this.getValue(parentIdx)) < 0) {
this.swap(pos, parentIdx);
pos = parentIdx;
parentIdx = this.getParentIndex(pos);
}
}
public T removeTop() {
T rst = this.getHeapTop();
this.data[0] = this.data[--this.size];
this.shiftdown(0);
return rst;
}
public boolean hasNext() {
return this.size > 0;
}
@SuppressWarnings("unchecked")
public T[] getData() {
return (T[]) this.data;
}
@SuppressWarnings("unchecked")
public T getValue(int index) {
return (T) this.data[index];
}
private int getParentIndex(int pos) {
return (pos - 1) / 2;
}
private int getLeftChildIdx(int pos) {
return pos * 2 + 1;
}
private int getRightChildIdx(int pos) {
return pos * 2 + 2;
}
private void swap(int idx1, int idx2) {
T tmp = this.getValue(idx1);
this.data[idx1] = this.getValue(idx2);
this.data[idx2] = tmp;
}
/**
* 节点值向下级交换,构造堆
*
* @param pos
*/
private void shiftdown(int pos) {
int leftChildIdx = this.getLeftChildIdx(pos);
// 没有子节点了
if (leftChildIdx >= this.size) {
return;
}
int rightChildIdx = getRightChildIdx(pos);
int toBeSwapIdx = leftChildIdx;
if (rightChildIdx < this.size
&& this.getValue(leftChildIdx).compareTo(
this.getValue(rightChildIdx)) > 0) {
toBeSwapIdx = rightChildIdx;
}
// swap
if (this.getValue(pos).compareTo(this.getValue(toBeSwapIdx)) > 0) {
this.swap(pos, toBeSwapIdx);
this.shiftdown(toBeSwapIdx);
}
}
public boolean isFull(){
return this.maxSize == this.size;
}
public int getMaxSize() {
return maxSize;
}
/**
* @param args
*/
public static void main(String[] args) {
Integer[] data = { 7, 12, 13, 24, 8, 6, 4, 27, 14, 8, 12, 56, 22 };
TopNHeap<Integer> heap = new TopNHeap<Integer>(data);
while (heap.hasNext()) {
System.out.print(heap.removeTop());
System.out.print(" ");
}
System.out.println(" ");
heap.initHeap(data);
for (int i = 0; i < 10; i++) {
heap.addToHeap(i);
}
while (heap.hasNext()) {
System.out.print(heap.removeTop());
System.out.print(" ");
}
System.out.println(" ");
heap = new TopNHeap<Integer>(10);
Random rd = new Random();
for (int i = 0; i < 20; i++) {
int value = rd.nextInt(100);
// System.out.print(value);
// System.out.print(" ");
heap.addToHeap(value);
}
System.out.println(" ");
while (heap.hasNext()) {
System.out.print(heap.removeTop());
System.out.print(" ");
}
}
}
测试结果:
4 6 7 8 8 12 12 13 14 22 24 27 56
7 8 8 8 9 12 12 13 14 22 24 27 56
60 61 64 65 67 67 71 74 74 97
分享到:
相关推荐
topk问题的Python实现,k-堆实现
标题中的“TOPK算法的Hash实现”指的是使用哈希数据结构来解决找出数据集中最大或最小的K个元素的问题。这种算法通常用于大数据处理和实时分析中,因为哈希表可以提供快速的查找和更新操作。 TOPK算法的核心是通过...
在C或C++中实现这个算法,可以使用STL库中的`priority_queue`,这是一个内置的最小堆实现。但由于我们要构建最大堆,我们可能需要自定义比较函数或者逆序存储元素。下面是一个简单的C++代码示例: ```cpp #include ...
在这个场景中,我们讨论的是一个用Java实现的简单Top-K算法。这个算法的目标是高效地找到一个数据集合中的前K个最大(或最小)的元素,而不需要对整个集合进行完整的排序。 在传统的排序方法中,如快速排序或归并...
5. **优化技巧**:在实现中,可能会用到最小堆或优先队列等数据结构,它们可以在O(log K)的时间复杂度内完成插入和删除操作,对于topK问题非常有效。 6. **代码实现**:“BinarySearchST-master”可能包含了一个...
### TopK 问题的五种解决方案 在计算机科学与数据处理领域中,TopK 问题是一种常见的需求场景,其核心任务是从一个数组或列表中找到最大的 K 个元素。这类问题广泛应用于各种场合,比如搜索引擎返回最相关的 K 条...
**Top K算法的堆实现步骤**: 1. 初始化一个大小为K的最小堆,用于存储出现次数最多的K个查询字符串及其出现次数。 2. 遍历日志中的每个查询字符串: - 如果堆未满(大小小于K),直接将查询字符串及其出现次数...
在Top K问题中,通常使用最小堆来实现。假设我们要找出最大的Top K个数,可以构建一个大小为K的小顶堆。小顶堆中最大的数即为Top K中的最小数。通过依次比较数据中的每个数与堆顶元素,如果比堆顶元素大,则替换堆顶...
而TOP-K问题通过堆实现,可以在O(k log k)的时间内找出前K个最大值,相比全排序整个数据集,大大提高了效率。 总的来说,掌握堆排序和如何解决TOP-K问题对于理解和优化算法性能至关重要。这两个概念不仅在理论上有...
下面将从两种方法来实现Java实现TopK问题:基于快排的TopK实现和堆排序实现TopK。 基于快排的TopK实现: 快排是最常见的排序算法之一,它可以在O(n log n)的时间复杂度内对数组进行排序。在快排的基础上,我们可以...
这个“java实现TOP查询”的作业来自东北大学软件学院的java期末项目,旨在让学生掌握分布式TOPK算法的基本实现。这里我们将深入探讨相关知识点。 首先,让我们了解什么是TOP查询。在数据库或数据处理中,TOP查询...
在解决TOP-K问题时,我们通常会用到最大堆或最小堆。 首先,让我们了解堆的基本操作: 1. **插入元素 (Heapify Up)**:当新元素插入堆时,需要确保它与它的父节点保持堆属性。如果新元素比父节点大(大顶堆)或小...
3. **全局TopK合并**:最后,将各个小文件的TopK结果合并,再次使用最小堆进行处理,以找出全局的TopK元素。在合并过程中,可能需要不断调整堆的结构,以保持堆的性质。这一步骤可能需要迭代几次,直到找到最终的Top...
`topk.py` 文件很可能包含了实现这一功能的Python代码。它可能使用了各种方法,比如优先队列(heapq库)、排序或者选择算法。其中,一种常见的高效解决方案是使用最小堆(min-heap),因为它可以在O(n log k)的时间...
文档通过之前的寻找最小k个数的问题作为铺垫,探讨了Top K算法的实现,特别是寻找最大k个数的情况。文章强调,虽然寻找最大k个数和最小k个数在原理上相似,但Top K算法在搜索引擎和大数据处理等领域有更广泛的应用。...
在上述文档中,提到了三种不同的Top K算法实现: 1. **寻找最小的第 k 个数**: 这个实现使用了快速选择算法,它是快速排序的一个变体,但目标不是完全排序数组,而是找到第 k 小的元素。通过选择一个枢轴元素并...