topk--堆排序--小顶堆
来源:互联网 发布:学术猫数据库 编辑:程序博客网 时间:2024/06/06 02:32
【问题描述】
假设需要我们在一堆海量数据中找出排名前k的数据;最好的方法是用最小堆排序,直接用前k个数据建立一个小顶堆,然后遍历剩余的数,
①如果此数<堆顶元素【说明:比k个数中最小的数还要小】,直接跳过此数,遍历下一个数;
②如果此数>堆顶的数,则将此数和堆顶的数交换,然后从堆顶向下调整堆,使其重新满足小顶堆。
【说明】堆的存储
一般用数组来表示堆,第i个节点的父节点下标为i/2-1;它的左右节点下标分别为:2*i+1和2*1+2
【代码】
一、从第i个点向下调整堆的过程
// 从i节点开始向下调整,n为节点总数,从i开始计算 i节点的子节点为 2*i+1, 2*i+2void MinHeapDown(int a[], int i, int n){ int j, temp;temp = a[i];j = 2 * i + 1;while (j < n){if (j + 1 < n && a[j + 1] < a[j]) //在左右孩子中找最小的j++;if (a[j] >= temp)break;a[i] = a[j]; //把较小的子结点往上移动,替换它的父结点i = j;j = 2 * i + 1;}a[i] = temp;}
二、建立最小堆的过程
【说明】从最后一个非叶节点开始,追个进行向下调整操作,保证当前节点的所有子节点是满足最小堆的,然后一直到根节点,保证这个堆是满足小顶堆的
//建立最小堆void MakeMinHeap(int a[], int n){for (int i = n / 2 - 1; i >= 0; i--)MinHeapDown(a, i, n);}
三、当来一个新数,需要替换堆顶元素时,替换堆顶元素,然后,从堆顶元素向下进行一次调整,即可使新堆满足小顶堆
//如果当前值key>堆顶元素,则进行替换操作,然后进行向下调整
void MinHeapReplaceHeader(int a[], int n,int key){a[0] = key;MinHeapDown(a, 0, n);}
void MinHeapDeleteNumber(int a[], int n) { for(int i=n-1;i>=0;i--){ //每次输出一个最小值后的调整过程 Swap(a[0], a[i]); MinHeapDown(a, 0, i); } //进行遍历,输出最终k个值的过程 for(int i=n-1;i>=0;i--) printf("%d ",a[i]);}
堆排序的时间复杂度为O(N*logN)
【话外音】
当然,若数据不是很大,也可以用快排先进行排序,然后直接输出前k个最大的数;数据量大的情况下,不提倡排序
0 0
- topk--堆排序--小顶堆
- 堆排序和TopK问题
- 堆与堆排序与topK问题
- 排序算法,堆算法实现TopK
- 排序算法,堆算法实现TopK
- topK问题解法之-堆排序
- 重温数据结构:堆,堆排序,优先队列,TopK问题
- 堆的应用----TopK问题和堆排序
- 堆的应用:topk问题以及堆排序
- Java 实现 堆排序 快速排序 以及 TopK问题(一)
- Java 实现 堆排序 快速排序 以及 TopK问题(二)
- 【面经笔记】堆排序与topk问题
- 堆及topk问题
- 堆及topk问题
- 最小堆解决topK问题
- c/c++ 堆排 topk
- 堆--优先级队列--topK问题
- Scala堆的方式进行Spark topK词频查询(根据value进行TreeMap排序)
- MATLAB中图像的几何操作
- 在 unity 中使用三种简单的方式实现实时时钟动画
- Cocos2d-x 图像渲染和动画——裁剪(ClippingNode)
- send pkt
- python usefull lib
- topk--堆排序--小顶堆
- JAVA源码剖析之---Object类(三)---toString,wait,notify,notifyAll,finalize方法的使用
- Fragment加入到Activity的两种方式
- 重构全局系统架构的方法与工具
- Go语言学习笔记10
- UIView——layout
- 编写一个makefile的简单实例
- Cocos2d-x 3.0数据结构——cocos2d::Vector
- Activity给Fragment传参