最大堆 最小堆 解决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.为了以更高的价格将股票卖给风险投资公 ...
随机推荐
- selenium自动化-java-封装断言
封装的断言. 1 package com.baidu.www; import org.testng.Assert; /* * 封装断言 */ public class assertion { stat ...
- Android 从网络中获取数据时 产生部分数据乱码的解决
产生部分数据乱码的解决 标签: android部分中文乱码 2014-04-12 23:24 12366人阅读 评论(10) 收藏 举报 分类: [Android 基础](15) 版权声明:本文为博主 ...
- HAOI2015 泛做
T1 有一棵点数为N的树,树边有边权.给你一个在0~N之内的正整数K,你要在这棵树中选择K个点,将其染成黑色,并将其他的N-K个点染成白色.将所有点染色后,你会获得黑点两两之间的距离加上白点两两之间的 ...
- Struts2 contentType属性列表
Struts2 contentType属性列表 博客分类: Struts 2 'ez' => 'application/andrew-inset', 'hqx' => 'applica ...
- 【原】Learning Spark (Python版) 学习笔记(二)----键值对、数据读取与保存、共享特性
本来应该上周更新的,结果碰上五一,懒癌发作,就推迟了 = =.以后还是要按时完成任务.废话不多说,第四章-第六章主要讲了三个内容:键值对.数据读取与保存与Spark的两个共享特性(累加器和广播变量). ...
- 一道有意思的笔试题引发的对于new操作符的思考
楼主比较喜欢看一些很短但很有意思的题目,无意间又瞥到了一题,大家不妨可以一试.(原题链接猛戳这里) function Fn1() { this.name = 'peter'; return { nam ...
- 【BZOJ 1065】【Vijos 1826】【NOI 2008】奥运物流
http://www.lydsy.com/JudgeOnline/problem.php?id=1065 https://vijos.org/p/1826 好难的题啊TWT ∈我这辈子也想不出来系列~ ...
- BZOJ 3223: Tyvj 1729 文艺平衡树
3223: Tyvj 1729 文艺平衡树 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 3628 Solved: 2052[Submit][Sta ...
- Python【第四章】:socket
ocket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字"向网络发出请求或者应答网络请求. socket起源于Uni ...
- Extjs 知识体系1-dom操作
操作dom 主要是Ext.element,主要是简单的操作 Ext.dom.CompositeElement // 操作dom集合 ps:Extjs 使用字面量{} 形式,不支持链式操作 一.获取元素 ...