最大堆 最小堆 解决TOPK问题
堆:实质是一颗完全二叉树,最大堆的特点:父节点值均大于子节点;最小堆的父节点值均小于子节点;
一般使用连续内存存储堆内的值,因而可以根据当前节点的索引值推断子节点的索引值:
节点i的父节点为(i-1)/2;
节点j的左子结点:j * 2 + 1;
节点j的右子结点:j * 2 + 2;
以下代码实现了最大堆最小堆,当比较函数使用std::greater,得到最大堆,当比较函数使用std::less得到最小堆;
代码及测试用例如下:
//最大最小堆
//MaxMinHeap.h #pragma once
#include <assert.h> using namespace std; template <typename T>
void mswap(T &a, T &b)
{
T tmp = a;
a = b;
b = tmp;
} template <typename T,typename Compare = std::less<T>>
class MaxMinHeap
{
public:
int hSize ; //堆空间
int hCurNum;//堆内已占用空间
T *data; private:
Compare comp;//比较函数
public:
MaxMinHeap(int size)
{
hSize = size;
assert(hSize>);
data = new T[hSize];
hCurNum = ;
};
~MaxMinHeap(void)
{
if(data!=NULL)
delete []data;
}; void headAdd(T num)
{
if (hCurNum==hSize)
{
if (comp(num,data[]))//greater 大顶堆 保留最小的K个数;less 小顶堆 保留最大的K个数
return;
data[]=num;
HeapFixDown(,hCurNum);
}
else
{
data[hCurNum++]=num;
HeapFixUp(hCurNum-);
}
};
//最大堆排序后得到升序序列;最小堆排序后得到降序序列
void sort()
{
for (int i=hCurNum-; i >= ; --i)
{
mswap(data[i],data[]);
HeapFixDown(,i);
}
} void GetHnum(T &n)//获取最大堆的最小值或者最小堆的最大值
{
n = data[];
};
void HeapFixUp(int index)
{
assert (index < hCurNum);
T tmp=data[index];
int j = (index - )/;//父节点
while(j>= && index !=)
{
if(comp(data[j],tmp))
break;
data[index]=data[j];
index = j;
j = (index - )/;
}
data[index]=tmp;
}; //从节点index开始进行向下调整
void HeapFixDown(int index, int n)
{
assert(index<hCurNum);
assert(n<hCurNum); T tmp=data[index];
int j = index*+;
while(j<n)
{
if(j+ < n && comp(data[j+],data[j]))//大顶堆中左右孩子找最大的,小顶堆左右孩子找最小的
++j;
if(comp(tmp,data[j]))
break;
data[index]=data[j];
index = j;
j = index*+;
}
data[index]=tmp;
};
}; #include <functional>
#include <iostream>
#include "MaxMinHeap.h " using namespace std; int main(int argc , char ** argv)
{
MaxMinHeap<float,greater<float>> test(); for (int i = ;i < ; ++i)
{
test.headAdd(-i*+);
}
for (int i = ; i < ; ++i)
{
cout<<test.data[i]<<endl;
}
test.sort();
for (int i = ; i < ; ++i)
{
cout<<test.data[i]<<" ";
}
cout<<endl;
return ;
}
最大堆 最小堆 解决TOPK问题的更多相关文章
- Java最小堆解决TopK问题
TopK问题是指从大量数据(源数据)中获取最大(或最小)的K个数据. TopK问题是个很常见的问题:例如学校要从全校学生中找到成绩最高的500名学生,再例如某搜索引擎要统计每天的100条搜索次数最多的 ...
- scala写算法-用小根堆解决topK
topK问题是指从大量数据中获取最大(或最小)的k个数,比如从全校学生中寻找成绩最高的500名学生等等. 本问题可采用小根堆解决.思路是先把源数据中的前k个数放入堆中,然后构建堆,使其保持堆序(可以简 ...
- Black Box--[优先队列 、最大堆最小堆的应用]
Description Our Black Box represents a primitive database. It can save an integer array and has a sp ...
- HDU 1425 sort(堆排序/快排/最大堆/最小堆)
传送门 Description 给你n个整数,请按从大到小的顺序输出其中前m大的数. Input 每组测试数据有两行,第一行有两个数n,m(0<n,m<1000000),第二行包含n个各不 ...
- PAT-1147(Heaps)最大堆和最小堆的判断+构建树
Heaps PAT-1147 #include<iostream> #include<cstring> #include<string> #include<a ...
- c++/java/python priority_que实现最大堆和最小堆
#include<iostream>#include<vector>#include<math.h>#include<string>#include&l ...
- Google 面试题:Java实现用最大堆和最小堆查找中位数 Find median with min heap and max heap in Java
Google面试题 股市上一个股票的价格从开市开始是不停的变化的,需要开发一个系统,给定一个股票,它能实时显示从开市到当前时间的这个股票的价格的中位数(中值). SOLUTION 1: 1.维持两个h ...
- C++ multiset通过greater、less指定排序方式,实现最大堆、最小堆功能
STL中的set和multiset基于红黑树实现,默认排序为从小到大. 定义三个multiset实例,进行测试: multiset<int, greater<int>> gre ...
- 502. IPO(最小堆+最大堆法 or 排序法)
题目: 链接:https://leetcode-cn.com/problems/ipo/submissions/ 假设 力扣(LeetCode)即将开始其 IPO.为了以更高的价格将股票卖给风险投资公 ...
随机推荐
- BZOJ1057[ZJOI2007]棋盘制作 [单调栈]
题目描述 国际象棋是世界上最古老的博弈游戏之一,和中国的围棋.象棋以及日本的将棋同享盛名.据说国际象棋起源于易经的思想,棋盘是一个8*8大小的黑白相间的方阵,对应八八六十四卦,黑白对应阴阳. 而我们的 ...
- CH Round #72树洞[二分答案 DFS&&BFS]
树洞 CH Round #72 - NOIP夏季划水赛 描述 在一片栖息地上有N棵树,每棵树下住着一只兔子,有M条路径连接这些树.更特殊地是,只有一棵树有3条或更多的路径与它相连,其它的树只有1条或2 ...
- Java的泛型反射
If the superclass is a parameterized type, the {@code Type} * object returned must accurately reflec ...
- Nginx编译参数.md
Nginx 介绍 简介 Nginx(发音同engine x)是一个网页服务器,它能反向代理HTTP, HTTPS, SMTP, POP3, IMAP的协议链接,以及一个负载均衡器和一个HTTP缓存. ...
- c# 调用c++DLL方法及注意事项
引用命名空间 using System.Runtime.InteropServices 调用方法: 一.静态加载 用DllImprot方式来加载c++DLL.如下格式: //对应c++方法 //voi ...
- HttpContext.Current.Session.SessionID相关问题及备忘
今天Tony提到说我们系统中会利用如下代码来判断用户是否过期. if (string.IsNullOrEmpty(UserContext.ConnectionSessionId)) { LogUIFa ...
- 点击按钮后到底发生了什么,Touch,LongClick或者Click?
按钮点击事件详解 最近一个项目需要给应用初始界面上的动态按钮添加在不同状态的变换效果,如点击(俗一点也可称为按压)后实现背景图的更换或者图标的缩放等效果.由于按钮点击的时间有长有短,所以采用OnTou ...
- inline-block元素间距
做项目过程中发现元素设置为inline-block后,彼此之间会有间距,有时候不是我们想要的效果,这时候就需要将间距去除掉. 后来上网查了下,已有前人总结了不少好的方法.这里主要借鉴了张鑫旭博客中介绍 ...
- [Bundling and Minification ] 四、总结
一.ASP.NET MVC 里面提供了一个默认的绑定集合BundleTable.Bundles 位于System.Web.Optimization下的静态类BundleTable中的一个静态变量.以下 ...
- JS中的进制转换以及作用
js的进制转换, 分为2进制,8进制,10进制,16进制之间的相互转换, 我们直接利用 对象.toString()即可实现: //10进制转为16进制 ().toString() // =>&q ...