结构之美——优先队列三大结构(三)——Pairing Heap
转自http://dsqiu.iteye.com/blog/1714961
1.Pairing Heap简介
斐波那契堆主要有两个缺点:编程实现难度较大和实际效率没有理论的那么快(由于它的存储结构和四个指针)。Pairing Heap的提出就是弥补斐波那契堆的两个缺点——编程简单操作的时间复杂度和斐波那契堆一样。
Pairing Heap其实就是一个具有堆(最大堆或最小堆)性质的树,它的特性不是由它的结构决定的,而是由于它的操作(插入,合并,减小一个关键字等)决定的。
1.1Pairing Heap的ADT
PairingHeapNode
{
int key;
struct PairingHeapNode* child;
struct PairingHeapNode* sibling;
struct PairingHeapNode* prev;
}PairHeap;
2.Pairing Heap 的操作
注意:图解过程是以最大堆来演示的,但是代码是以最小堆来写的,见谅!
2.1.合并两个子堆
static PairHeap* merge_subheaps(PairHeap *p, PairHeap *q) { if(q == NULL) return p; else if(p->key <= q->key) { q->prev = p; p->sibling = q->sibling; if(p->sibling != NULL) p->sibling->prev = p; q->sibling = p->child; if(q->sibling != NULL) q->sibling->prev = q; p->child = q; return p; } else { q->prev = p->prev; p->prev = q; p->sibling = q->child; if(p->sibling != NULL) p->sibling->prev = p; q->child = p; return q; } }
2.2. 插入一个结点
PairHeap* PairHeap_insert(PairHeap *p, int key) { PairHeap *node; node = (PairHeap*)malloc(sizeof(*node)); if(node == NULL) return NULL; node->key = key; node->child = node->sibling = node->prev = NULL; if(p == NULL) return node; else return merge_subheaps(p, node); }
2.3.增加(减小)一个关键字
PairHeap* PairHeap_DecreaseKey(PairHeap *p, PairHeap *pos, int d) { if(d < 0) return p; pos->key = pos->key - d; if(p == pos) return p; if(pos->sibling != NULL) pos->sibling->prev = pos->prev; if(pos->prev->child = pos) pos->prev->child = pos->sibling; else pos->prev->sibling = p->sibling; p->sibling = NULL; return merge_subheaps(p, pos); }
2.5.删除最小结点
3.Pairing Heap完整代码实现
#include <stdlib.h> typedef struct PairingHeapNode { int key; struct PairingHeapNode* child; struct PairingHeapNode* sibling; struct PairingHeapNode* prev; }PairHeap; static PairHeap* merge_subheaps(PairHeap *p, PairHeap *q); static PairHeap* combine_siblings(PairHeap *p); PairHeap* PairHeap_insert(PairHeap *p, int key) { PairHeap *node; node = (PairHeap*)malloc(sizeof(*node)); if(node == NULL) return NULL; node->key = key; node->child = node->sibling = node->prev = NULL; if(p == NULL) return node; else return merge_subheaps(p, node); } PairHeap* PairHeap_DecreaseKey(PairHeap *p, PairHeap *pos, int d) { if(d < 0) return p; pos->key = pos->key - d; if(p == pos) return p; if(pos->sibling != NULL) pos->sibling->prev = pos->prev; if(pos->prev->child = pos) pos->prev->child = pos->sibling; else pos->prev->sibling = p->sibling; p->sibling = NULL; return merge_subheaps(p, pos); } PairHeap* PairHeap_DeleteMin(int *key, PairHeap *p) { PairHeap *new_root; if(p == NULL) return NULL; else { *key = p->key; if(p->child != NULL) new_root = combine_siblings(p->child); free(p); } return new_root; } static PairHeap* combine_siblings(PairHeap *p) { PairHeap *tree_array[1024]; int i, count; if(p->sibling == NULL) return p; for(count = 0; p != NULL; count++) { tree_array[count] = p; p->prev->sibling = NULL; p = p->sibling; } tree_array[count] = NULL; for(i = 1; i < count; i++) tree_array[i] = merge_subheaps(tree_array[i-1], tree_array[i]); return tree_array[count-1]; } static PairHeap* merge_subheaps(PairHeap *p, PairHeap *q) { if(q == NULL) return p; else if(p->key <= q->key) { q->prev = p; p->sibling = q->sibling; if(p->sibling != NULL) p->sibling->prev = p; q->sibling = p->child; if(q->sibling != NULL) q->sibling->prev = q; p->child = q; return p; } else { q->prev = p->prev; p->prev = q; p->sibling = q->child; if(p->sibling != NULL) p->sibling->prev = p; q->child = p; return q; } }
小结
终于到小结了,这篇文章写得比较吃力,如斐波那契堆的“减小一个关键字”的操作我就对使用级联剪切还没有找到解释,还有还没有找到Pairing Heap的定义,唯独只有自己理解和揣测(比如pairing heap没有明确的定义,本人个人理解pairing heap的独特性一定在他的操作,即行为决定特征)但总归还是相对完整,希望能对你有说帮助。如果你有任何建议、批评或补充,还请你不吝提出,不甚感激。更多参考请移步互联网。
参考:
①酷~行天下: http://mindlee.net/2011/09/26/binomial-heaps/
②Björn B. Brandenburg:http://www.cs.unc.edu/~bbb/#binomial_heaps
③酷~行天下: http://mindlee.net/2011/09/29/fibonacci-heaps/
④Adoo's blog :http://www.roading.org/algorithm/introductiontoalgorithm/%E6%96%90%E6%B3%A2%E9%82%A3%E5%A5%91%E5%A0%86fibonacci-heaps.html
⑤Golden_Shadow:http://blog.csdn.net/golden_shadow/article/details/6216921
⑥Sartaj Sahni:http://www.cise.ufl.edu/~sahni/dsaaj/enrich/c13/pairing.htm
⑦C++ template Fibonacci heap, with demonstration:http://ideone.com/9jYnv
⑧"The pairing heap: a new form of self-adjusting heap":http://www.cs.cmu.edu/afs/cs.cmu.edu/user/sleator/www/papers/pairing-heaps.pdf
⑨Vikas Tandi :http://programmingpraxis.com/2009/08/14/pairing-heaps/
⑩http://www.cise.ufl.edu/~sahni/cop5536/slides/lec156.pdf
⑩+1: 算法导论和维基百科
结构之美——优先队列三大结构(三)——Pairing Heap相关推荐
- 结构之美——优先队列基本结构(四)——二叉堆、d堆、左式堆
实现优先队列结构主要是通过堆完成,主要有:二叉堆.d堆.左式堆.斜堆.二项堆.斐波那契堆.pairing 堆等. 1. 二叉堆 1.1. 定义 完全二叉树,根最小. 存储时使用层序. 1.2. 操作 ...
- Jemalloc 深入分析 之 配对堆Pairing Heap
为了更好的阅读效果,推荐下载pdf文档: 详细文章请参考:<jemalloc 深入分析> https://github.com/everschen/tools/blob/master/DO ...
- 史上最强Js流程控制三大结构
大家好!我是萧寒,今天给大家分享的是流程控制的三大语句. 文章目录 初识JavaScript(四) 流程控制语句 顺序结构 分支结构 if语句 if的加强版if else语句(双分支语句) if 语句 ...
- 麦肯锡著名的三大结构化工具:金字塔原理、MECE和逻辑树
今天给大家重点介绍一下,麦肯锡著名的三大结构化工具:金字塔原理.MECE原理和逻辑树: 关于金字塔原理 对于金字塔原理这种逻辑思考工具,要想掌握,是需要花时间进行反复练习的,包括在培训的现场,是需要进 ...
- Linux 物理内存管理涉及的三大结构体之struct zone
从Linux 物理内存管理涉及的三大结构体之struct page 中,大概知道了UMA和NUMA概念,同时也知道在每个node对应的内存范围内,都会将其分成不同的内存管理区域zone.之所以分成几类 ...
- 【濡白的C语言】初学者-从零开始-3(三大结构—顺序结构,分支结构,循环结构)
前言 学习C语言,必须要掌握的是三大结构--顺序.分支和循环.一切C语言程序都可以用这三个结构总结,因此熟练掌握它们,对于写程序以及理解程序都是非常有必要的. 目录 顺序结构 变量声明 函数声明 循环 ...
- 详细介绍C语言三大结构(顺序结构,分支结构,循环结构)
目录 1. 顺序结构 1.1介绍顺序结构 2. 分支结构 2.1 分支结构的介绍与实现逻辑 2.2 if 语句实现分支 2.3 switch case语句 2.4两者的区别 3. 循环 ...
- Java的三大结构理解
从结构化程序设计角度出发,java有三种结构:顺序.选择.循环. 一.顺序结构: JAVA的基本结构就是顺序结构,除非特别指明,否则就按照顺序一句一句执行顺序结构是最简单的算法结构,语句与语句之间,框 ...
- Java 结构体之 JavaStruct 使用教程三 JavaStruct 数组进阶
经过前面两篇博客的介绍,相信对于 JavaStruct 的认识以及编程使用,读者已经有一定的基础了.只要理解和实践结合起来,掌握还是很容易的.下面进行一些数组使用方面的实例说明及演示. 在结构体类中使 ...
最新文章
- python中值滤波去除反光_Python 实现中值滤波、均值滤波的方法
- 方舟修改显示服务器个数,方舟生存进化服务器模式设置教程
- noa格式转java_用IDEA查看反编译 - osc_1loi8uc4的个人空间 - OSCHINA - 中文开源技术交流社区...
- OkHttp实现登录注册验证
- 祝福!微软 46 周年生日快乐!
- linux下延时1ms用什么函数,Linux下1ms分辨率定时器推荐方式
- 钉钉在线求饶?五星分期付款?爬取钉钉App Store真实评价数据并分析
- CUDA中的复数定义、开内存空间以及运算
- Python库:time库
- [NLP]OpenNLP标记器的使用
- Linux:管线命令
- “流量注入”***模式的探讨
- 编写二分查找和使用集合类的二分查找实现
- [论文写作-词汇] 这么多特别,该用哪个?special especial specific particular peculiar exceptional extraordinary
- 几何分布(一种离散分布)
- python中字典的索引_python字典索引
- 《很杂很杂的杂学知识》 学习笔记
- BeagleBone Black– 智能家居控制系统 LAS - ESP8266 UDP 服务
- 06-Python类和对象
- 重新认识java(五) ---- 面向对象之多态(向上转型与向下转型)
热门文章
- 关于AD转换设计的一些经验总结(转载)
- ios -获取手机唯一imei码
- 淘宝客用户与订单的绑定
- (LDO)MX6207 低消耗电流高 PSRR 500mA CMOS LDO
- java使用poi实现导出表格模板
- shell脚本在linux中运行报错:: command not found: line 2:
- 2020年研究生考试,加油!
- 【天池龙珠计划寒假训练营】python学习笔记(四):利用Pandas分析美国选民总统喜好度
- 10.21.2010吉他课笔记
- 最新最全MySQL 8知识,关注这篇就够了!