堆:实质是一颗完全二叉树,最大堆的特点:父节点值均大于子节点;最小堆的父节点值均小于子节点;

一般使用连续内存存储堆内的值,因而可以根据当前节点的索引值推断子节点的索引值:

节点i的父节点为(i-1)/2;

节点j的左子结点:j * 2 + 1;

节点j的右子结点:j * 2 + 2;

以下代码实现了最大堆最小堆,当比较函数使用std::greater,得到最大堆,当比较函数使用std::less得到最小堆;

代码及测试用例如下:

  1. //最大最小堆
  2. //MaxMinHeap.h
  3.  
  4. #pragma once
  5. #include <assert.h>
  6.  
  7. using namespace std;
  8.  
  9. template <typename T>
  10. void mswap(T &a, T &b)
  11. {
  12. T tmp = a;
  13. a = b;
  14. b = tmp;
  15. }
  16.  
  17. template <typename T,typename Compare = std::less<T>>
  18. class MaxMinHeap
  19. {
  20. public:
  21. int hSize ; //堆空间
  22. int hCurNum;//堆内已占用空间
  23. T *data;
  24.  
  25. private:
  26. Compare comp;//比较函数
  27. public:
  28. MaxMinHeap(int size)
  29. {
  30. hSize = size;
  31. assert(hSize>);
  32. data = new T[hSize];
  33. hCurNum = ;
  34. };
  35. ~MaxMinHeap(void)
  36. {
  37. if(data!=NULL)
  38. delete []data;
  39. };
  40.  
  41. void headAdd(T num)
  42. {
  43. if (hCurNum==hSize)
  44. {
  45. if (comp(num,data[]))//greater 大顶堆 保留最小的K个数;less 小顶堆 保留最大的K个数
  46. return;
  47. data[]=num;
  48. HeapFixDown(,hCurNum);
  49. }
  50. else
  51. {
  52. data[hCurNum++]=num;
  53. HeapFixUp(hCurNum-);
  54. }
  55. };
  56. //最大堆排序后得到升序序列;最小堆排序后得到降序序列
  57. void sort()
  58. {
  59. for (int i=hCurNum-; i >= ; --i)
  60. {
  61. mswap(data[i],data[]);
  62. HeapFixDown(,i);
  63. }
  64. }
  65.  
  66. void GetHnum(T &n)//获取最大堆的最小值或者最小堆的最大值
  67. {
  68. n = data[];
  69. };
  70. void HeapFixUp(int index)
  71. {
  72. assert (index < hCurNum);
  73. T tmp=data[index];
  74. int j = (index - )/;//父节点
  75. while(j>= && index !=)
  76. {
  77. if(comp(data[j],tmp))
  78. break;
  79. data[index]=data[j];
  80. index = j;
  81. j = (index - )/;
  82. }
  83. data[index]=tmp;
  84. };
  85.  
  86. //从节点index开始进行向下调整
  87. void HeapFixDown(int index, int n)
  88. {
  89. assert(index<hCurNum);
  90. assert(n<hCurNum);
  91.  
  92. T tmp=data[index];
  93. int j = index*+;
  94. while(j<n)
  95. {
  96. if(j+ < n && comp(data[j+],data[j]))//大顶堆中左右孩子找最大的,小顶堆左右孩子找最小的
  97. ++j;
  98. if(comp(tmp,data[j]))
  99. break;
  100. data[index]=data[j];
  101. index = j;
  102. j = index*+;
  103. }
  104. data[index]=tmp;
  105. };
  106. };
  107.  
  108. #include <functional>
  109. #include <iostream>
  110. #include "MaxMinHeap.h "
  111.  
  112. using namespace std;
  113.  
  114. int main(int argc , char ** argv)
  115. {
  116. MaxMinHeap<float,greater<float>> test();
  117.  
  118. for (int i = ;i < ; ++i)
  119. {
  120. test.headAdd(-i*+);
  121. }
  122. for (int i = ; i < ; ++i)
  123. {
  124. cout<<test.data[i]<<endl;
  125. }
  126. test.sort();
  127. for (int i = ; i < ; ++i)
  128. {
  129. cout<<test.data[i]<<" ";
  130. }
  131. cout<<endl;
  132. return ;
  133. }

最大堆 最小堆 解决TOPK问题的更多相关文章

  1. Java最小堆解决TopK问题

    TopK问题是指从大量数据(源数据)中获取最大(或最小)的K个数据. TopK问题是个很常见的问题:例如学校要从全校学生中找到成绩最高的500名学生,再例如某搜索引擎要统计每天的100条搜索次数最多的 ...

  2. scala写算法-用小根堆解决topK

    topK问题是指从大量数据中获取最大(或最小)的k个数,比如从全校学生中寻找成绩最高的500名学生等等. 本问题可采用小根堆解决.思路是先把源数据中的前k个数放入堆中,然后构建堆,使其保持堆序(可以简 ...

  3. Black Box--[优先队列 、最大堆最小堆的应用]

    Description Our Black Box represents a primitive database. It can save an integer array and has a sp ...

  4. HDU 1425 sort(堆排序/快排/最大堆/最小堆)

    传送门 Description 给你n个整数,请按从大到小的顺序输出其中前m大的数. Input 每组测试数据有两行,第一行有两个数n,m(0<n,m<1000000),第二行包含n个各不 ...

  5. PAT-1147(Heaps)最大堆和最小堆的判断+构建树

    Heaps PAT-1147 #include<iostream> #include<cstring> #include<string> #include<a ...

  6. c++/java/python priority_que实现最大堆和最小堆

    #include<iostream>#include<vector>#include<math.h>#include<string>#include&l ...

  7. Google 面试题:Java实现用最大堆和最小堆查找中位数 Find median with min heap and max heap in Java

    Google面试题 股市上一个股票的价格从开市开始是不停的变化的,需要开发一个系统,给定一个股票,它能实时显示从开市到当前时间的这个股票的价格的中位数(中值). SOLUTION 1: 1.维持两个h ...

  8. C++ multiset通过greater、less指定排序方式,实现最大堆、最小堆功能

    STL中的set和multiset基于红黑树实现,默认排序为从小到大. 定义三个multiset实例,进行测试: multiset<int, greater<int>> gre ...

  9. 502. IPO(最小堆+最大堆法 or 排序法)

    题目: 链接:https://leetcode-cn.com/problems/ipo/submissions/ 假设 力扣(LeetCode)即将开始其 IPO.为了以更高的价格将股票卖给风险投资公 ...

随机推荐

  1. selenium自动化-java-封装断言

    封装的断言. 1 package com.baidu.www; import org.testng.Assert; /* * 封装断言 */ public class assertion { stat ...

  2. Android 从网络中获取数据时 产生部分数据乱码的解决

    产生部分数据乱码的解决 标签: android部分中文乱码 2014-04-12 23:24 12366人阅读 评论(10) 收藏 举报 分类: [Android 基础](15) 版权声明:本文为博主 ...

  3. HAOI2015 泛做

    T1 有一棵点数为N的树,树边有边权.给你一个在0~N之内的正整数K,你要在这棵树中选择K个点,将其染成黑色,并将其他的N-K个点染成白色.将所有点染色后,你会获得黑点两两之间的距离加上白点两两之间的 ...

  4. Struts2 contentType属性列表

    Struts2 contentType属性列表 博客分类: Struts 2   'ez' => 'application/andrew-inset', 'hqx' => 'applica ...

  5. 【原】Learning Spark (Python版) 学习笔记(二)----键值对、数据读取与保存、共享特性

    本来应该上周更新的,结果碰上五一,懒癌发作,就推迟了 = =.以后还是要按时完成任务.废话不多说,第四章-第六章主要讲了三个内容:键值对.数据读取与保存与Spark的两个共享特性(累加器和广播变量). ...

  6. 一道有意思的笔试题引发的对于new操作符的思考

    楼主比较喜欢看一些很短但很有意思的题目,无意间又瞥到了一题,大家不妨可以一试.(原题链接猛戳这里) function Fn1() { this.name = 'peter'; return { nam ...

  7. 【BZOJ 1065】【Vijos 1826】【NOI 2008】奥运物流

    http://www.lydsy.com/JudgeOnline/problem.php?id=1065 https://vijos.org/p/1826 好难的题啊TWT ∈我这辈子也想不出来系列~ ...

  8. BZOJ 3223: Tyvj 1729 文艺平衡树

    3223: Tyvj 1729 文艺平衡树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 3628  Solved: 2052[Submit][Sta ...

  9. Python【第四章】:socket

    ocket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字"向网络发出请求或者应答网络请求. socket起源于Uni ...

  10. Extjs 知识体系1-dom操作

    操作dom 主要是Ext.element,主要是简单的操作 Ext.dom.CompositeElement // 操作dom集合 ps:Extjs 使用字面量{} 形式,不支持链式操作 一.获取元素 ...