最大堆

最大堆和最小堆基本概念

早过忘川 提交于 2019-11-29 11:20:53
堆和栈的区别: 一、堆栈空间分配区别:   1、栈(操作系统):由操作系统自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈;   2、堆(操作系统): 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收,分配方式倒是类似于链表。 二、堆栈缓存方式区别:   1、栈使用的是一级缓存, 他们通常都是被调用时处于存储空间中,调用完毕立即释放;   2、堆是存放在二级缓存中,生命周期由虚拟机的垃圾回收算法来决定(并不是一旦成为孤儿对象就能被回收)。所以调用这些对象的速度要相对来得低一些。    三、堆栈数据结构区别:   堆(数据结构):堆可以被看成是一棵树,如:堆排序;   栈(数据结构):一种先进后出的数据结构。 最大堆和最小堆是二叉堆的两种形式。 最大堆:根结点的键值是所有堆结点键值中最大者,且每个结点的值都比其孩子的值大。 最小堆:根结点的键值是所有堆结点键值中最小者,且每个结点的值都比其孩子的值小。 堆树的定义如下 : (1)堆树是一颗完全二叉树; (2)堆树中某个节点的值总是不大于或不小于其孩子节点的值; (3)堆树中每个节点的子树都是堆树。 当父节点的键值总是大于或等于任何一个子节点的键值时为最大堆。 当父节点的键值总是小于或等于任何一个子节点的键值时为最小堆。如下图所示,左边为最大堆,右边为最小堆。 具体代码实现参考以下链接:

Leetcode 373. 查找和最小的K对数字 解题思路及C++实现

心已入冬 提交于 2019-11-28 13:48:07
解题思路: 使用最大堆来存储k个和最小的数组组合,然后每进来一个数组组合,只需要和最大堆的堆顶进行比较即可。 用C++的priority_queue实现最大堆时,需要用一下pair来组合来自nums1和nums2数组的数,然后自己写一个比较结构体cmp,比较数组和的大小。 在循环中的一个trick在于,限制为访问nums1和nums2的前k个数即可。所以那一部分的时间复杂度为O(k*k)。 class Solution { public: vector<vector<int>> kSmallestPairs(vector<int>& nums1, vector<int>& nums2, int k) { if(k == 0) return {{}}; priority_queue<pair<int, int>, vector<pair<int, int>>, cmp> pq; //最大堆 for(int i = 0; i < nums1.size() && i < k; i++){ for(int j = 0; j < nums2.size() && j < k; j++){ pq.push(make_pair(nums1[i], nums2[j])); if(pq.size() > k) pq.pop(); } } //将结果放到res中 vector<vector<int> >

剑指offer 数据流中的中位数

99封情书 提交于 2019-11-28 08:53:01
题目描述 如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。我们使用Insert()方法读取数据流,使用GetMedian()方法获取当前读取数据的中位数。 思路:利用两个优先队列,最大堆始终保存前一半数据,最小堆始终保存后一半数据,当两个优先队列长度一样时,将数压入最小堆。 1 class Solution { 2 priority_queue<int, vector<int>, less<int> > p; //最大堆 3 priority_queue<int, vector<int>, greater<int> > q; //最小堆 4 public: 5 void Insert(int num) 6 { 7 //偶数个,应该压入最小堆 8 if (((p.size() + q.size()) & 1) == 0) { 9 if (p.size() > 0 && num < p.top()) { 10 int temp = p.top(); 11 p.pop(); 12 p.push(num); 13 q.push(temp); 14 } else { 15 q.push(num); 16 } 17 } else { //奇数个

二叉树——堆

一个人想着一个人 提交于 2019-11-27 08:32:34
一、堆的性质   结构性:用数组表示的完全二叉树   有序性:任意一结点的关键字是其子树所有结点的最大值(或最小值) 二、最大堆的操作 1、创建一个空的最大堆,堆从下标为1的地方开始存放(根结点下标为1) 2、最大堆的插入 首先,把要插入的结点放在数组的末尾,假设下标为H->size + 1 再将它与父结点比较,如果它比父结点大,两者互换位置 直到它比父结点小,这时候下标为0的很大的元素起到了哨兵作用。 3、最大堆的删除:删除最大的元素,然后再调整剩余结点,使其仍然是一个最大堆 把最大堆的最后一个元素a挪到根结点 找出a现在的左右儿子中较大的那个 如果a比左右儿子中较大的那个要小 互换位置 继续比较a与左右儿子中较大的那个 直到a比左右儿子都要大 4、最大堆的建立:将N个元素按最大堆的要求存储在一维数组中 方法1:一个一个插入,效率较低 方法2:在线性时间复杂度下建立最大堆     (1)将N个元素按输入顺序存入,先满足完全二叉树的结构特性     (2)调整各结点位置,以满足最大堆的有序性 一个结点,左子树是一个最大堆,右子树是一个最大堆 从删除操作,我们已经知道如何将他们三者调成一个最大堆 那么现在我们可以倒过来,逐步建立最大堆 下图中,p表示结点——左子树——右子树模型中结点的下标 H表示完全二叉树,一开始不是最大堆,但执行完PerDown后是最大堆 来源: https:/

CDH5.10 配置

◇◆丶佛笑我妖孽 提交于 2019-11-27 07:24:49
HDFS: dfs.datanode.du.reserved 100g (计算方法 磁盘总容量*0.05+50g)其中50g适量即可 其他参数指定一些日志目录和datanode目录 rebalance阈值 2 不启用hdfs权限 启用zookeeper 还有一些进程的内存限制大小 记得配置HA dfs.datanode.handler.count=30 dfs.namenode.handler.count=70 HBASE: 配置master和regionserver的内存限制即可 zookeeper.session.timeout=240000 HIVE: hive.exec.reducers.bytes.per.reducer =1g hive.merge.mapredfiles = true //输出合并 hive.merge.smallfiles.avgsize = 64m //输出合并 hive.fetch.task.conversion = more hive.exec.compress.output=true (如果impala需要访问结果表,可以不压缩) mapred.output.compression.codec=org.apache.hadoop.io.compress.GzipCodec(与上条结合使用) hive.exec.compress

算法导论第六章 堆排序

不羁岁月 提交于 2019-11-26 14:58:27
主要内容: 堆、最大堆、最小堆的基本概念 堆的操作:调整、创建、排序 采用堆实现优先级队列 基本概念 堆 ( heap )亦被称为: 优先队列 ( priority queue ) 逻辑定义: n个元素序列{k 1 ,k 2 ...k i ...k n },当且仅当满足下列关系时称之为堆: (k i <= k 2i ,k i <= k 2i+1 )或者(k i >= k 2i ,k i >= k 2i+1 ), (i = 1,2,3,4...n/2) 堆的实现通过构造 二叉堆 (binary heap),实为二叉树的一种。 性质 : 1、任意节点小于或大于它的所有后裔,最小元或最大元在堆的根上( 堆序性 )。将根节点最大的堆叫做 最大堆或大根堆 ,根节点最小的堆叫做 最小堆或小根堆 。常见的堆有二叉堆、斐波那契堆等。 2、堆总是一棵完全树。堆只需要满足父节点大于两个子节点,而子节点之间没有要求。作为一颗完全树,一层中的节点是从左到右填满的。如果一个节点没有左儿子,那么它一定没有右儿子。并且在第h层中如果存在节点,那么第h-1层必须是填满的。 堆的操作 调整堆 void adjust_max_heap_recursive(int *datas, int length, int i)//递归调用,最大堆调整 { int left,right,largest; int temp;