萌新笔记之堆(heap)
前言(萌新感想):
以前用STL的queue啊stack啊priority_queue啊,一直很想懂原理,现在终于课上到了priority_queue,还有就是下周期中考,哈哈,所以写几篇blog总结一下。
这里萌新讲下堆这个好东西;
堆的定义:
如果搞过ACM的童鞋应该会使用STL的priority_queue,堆就是STL的priority_queue。
堆是一种特殊的队列,从堆中取元素的依据是元素优先权大小,而不是元素进入队的先后顺序;
直接切入主题吧;
堆最常用的结构是二叉树,一棵完全二叉树,而完全二叉树由于其结点特别规律,所以可以用数组直接模拟。
下面介绍几个堆(以完全二叉树的形式):
最大堆:每个结点上的元素不小于其子节点元素的值;
最小堆:每个结点上的元素不大于其子节点元素的值;
拿最大堆来讲几个操作:
创建,插入,删除,建立最大元素;
下面参考自陈越姥姥版数据结构
用C语言(窝觉得好**)描述最大堆结构;
先定义:
typedef struct HeapStruct* MaxHeap;
struct HeapStruct
{
int *Elements; //存储元素的数组;
int Size; //堆的当前元素;
int Capacity; //堆的最大容量;
};
有人会说,卧槽为什么要结构体啊,明明说好的数组可以直接处理,为毛不用数组啊,而且结构体里面还有指针,好烦(繁)啊!
萌新想说,这样严谨吧,其实差不多啊,无非是换种方式而已;PS:ACM中不是很常用指针吧,说错,不是不常用指针,而是不常用动态开辟内存,时间很慢。
而且指针如果用的灵活,那是很超神的能力啊!
创建最大堆:
MaxHeap Creat(int MaxSize) //创建容量为MaxSize 空的最大堆
{
MaxHeap H;
int INF=0x3f3f3f3f;
H=(MaxHeap)malloc(sizeof(struct HeapStruct)); //都是动态开辟内存,不用深究
H->Elements=(int *)malloc((MaxSize+1)*sizeof(int));
H->Size=0; //初始化为0;
H->Elements[0]=INF; //作为一个”哨兵“为大于堆中所有可能元素的值;
return H;
}
最大堆的插入:
我们先假设这个元素插在了Size+1这个结点上,
①:他比他的父节点的值小,OK,那就躺着吧,插入完成;
②:可惜他比他的父节点大啊,那么。。。交换就好了嘛,交换以后一定是合法的啊。
这里有一种写法很牛逼啊,比普通交换好很多;
void Insert(MaxHeap H,int item) //item 是要插入的元素,这里称目标;
{
int i;
if(isFull(H)) //先判断一下是不是已经满了
{
printf("最大堆已满\n");
return;
}
i=++H->Size; //先默认目标被插在了新开的结点
//对下面的循环细说一下,如果目标比他的父节点大的话,那么交换,可以看到目标并没有存到父节点上,然后i/=2使得往上继续判断,如果>目标就会弹出循环;
//最后很有可能他成了整个完全二叉树的根,这里目标的编号是1,所以这个编号0就发挥作用了,一定比他大啊;
for( ; H->Elements[i/2] < item; i/=2)
H->Elements[i]=H->Elements[i/2];
H->Elements[i]=item;
}
最大堆的删除:
一开始爷爷做主。
我们浅显地可以看到拿走了最大的元素(即爷爷被带走了),那么肯定就是要个大的子结点(最大的爸爸)来顶替他的位置。
然后处理大的那个子节点被顶替上去了,所以又要安排一个最大的孙子顶替。
所以一直一直要处理好,但是你这样一直一直顶替会有个问题,可能会构造不成一棵完全二叉树。
bool isFull(MaxHeap H)
{ }
void DeleteMax(MaxHeap H)
{
int Parent,Child;
int temp;
if(IsEmpty(H))
{
printf("堆为空\n");
return;
}
temp=H->Elements[H->Size--]; //取末尾元素
//从根开始填
for(Parent=1; Parent*2<=H->Size; Parent = Child)
{
Child=Parent*2;
if(Child!=H->Size&&(H->Elements[Child+1]>H->Elements[Child])) //如果没有右儿子就是左儿子,如果有在左右儿子节点找一个大的,
Child++;
if(temp>=H->Elements[Child]) //如果比末尾元素比两个儿子都大,直接填他就行了
break;
else
H->Elements[Parent]=H->Elements[Child]; //不是的话就替换,然后往下继续判断;
}
H->Elements[Parent]=temp;
}
最大堆的建立:
然后依次减减减,也就是判断每一层的结点啊;
void BuildMaxHeap(MaxHeap H)
{
int i,Parent,Child;
int temp;
for(i=H->Size/2; i>0 ; --i)
{
temp=H->Elements[i];
for(Parent=i; Parent*2<=H->Size; Parent=Child)
{
Child=Parent*2;
if(Child!=H->Size&&(H->Elements[Child+1]>H->Elements[Child])) //如果没有右儿子就是左儿子,如果有在左右儿子节点找一个大的,
Child++;
if(temp>=H->Elements[Child]) //如果比末尾元素比两个儿子都大,直接填他就行了
break;
else
H->Elements[Parent]=H->Elements[Child]; //不是的话就替换,然后往下继续判断;
}
H->Elements[Parent]=temp;
}
}
萌新笔记之堆(heap)的更多相关文章
- 萌新笔记——C++里创建 Trie字典树(中文词典)(三)(联想)
萌新做词典第三篇,做得不好,还请指正,谢谢大佬! 今天把词典的联想做好了,也是比较low的,还改了之前的查询.遍历等代码. Orz 一样地先放上运行结果: test1 ID : char : 件 w ...
- 萌新笔记——C++里创建 Trie字典树(中文词典)(二)(插入、查找、导入、导出)
萌新做词典第二篇,做得不好,还请指正,谢谢大佬! 做好了插入与遍历功能之后,我发现最基本的查找功能没有实现,同时还希望能够把内存的数据存入文件保存下来,并可以从文件中导入词典.此外,数据的路径是存在配 ...
- 萌新笔记——C++里创建 Trie字典树(中文词典)(一)(插入、遍历)
萌新做词典第一篇,做得不好,还请指正,谢谢大佬! 写了一个词典,用到了Trie字典树. 写这个词典的目的,一个是为了压缩一些数据,另一个是为了尝试搜索提示,就像在谷歌搜索的时候,打出某个关键字,会提示 ...
- 萌新笔记之Nim取石子游戏
以下笔记摘自计算机丛书组合数学,机械工业出版社. Nim取石子游戏 Nim(来自德语Nimm!,意为拿取)取石子游戏. 前言: 哇咔咔,让我们来追寻娱乐数学的组合数学起源! 游戏内容: 有两个玩家面对 ...
- 萌新笔记——用KMP算法与Trie字典树实现屏蔽敏感词(UTF-8编码)
前几天写好了字典,又刚好重温了KMP算法,恰逢遇到朋友吐槽最近被和谐的词越来越多了,于是突发奇想,想要自己实现一下敏感词屏蔽. 基本敏感词的屏蔽说起来很简单,只要把字符串中的敏感词替换成"* ...
- 萌新笔记——git的问题(error: object file .git/objects/* is empty...)的解决方案及对git版本库文件的了解
由于操作不当,导致git版本库出了大问题,如下所示: error: object file .git/objects/8b/61d0135d3195966b443f6c73fb68466264c68e ...
- Python萌新笔记
Mychael上了大学,对Python产生了浓厚的兴趣,便开始了Python的学习 学习的时候,感觉Python确实比以往学的C++表达简洁很多,而又不失强大 以后的学习笔记就记在这啦 变量 Pyth ...
- 萌新笔记——linux下查看内存的使用情况
windows上有各种软件可以进行"一键加速"之类的操作,释放掉一些内存(虽然我暂时不知道是怎么办到的,有待后续学习).而任务管理器也可以很方便地查看各进程使用的内存情况,如下图: ...
- 萌新笔记——vim命令“=”、“d”、“y”的用法(结合光标移动命令,一些场合会非常方便)
vim有许多命令,网上搜有一堆贴子.文章列举出各种功能的命令. 对于"="."d"."y",我在无意中发现了它们所具有的相同的一些用法,先举 ...
随机推荐
- UML类图组成
本文转载至 http://blog.csdn.net/fengsh998/article/details/8105666 UML类图的相关知识,UML类图(Classdiagram)是最常用的 ...
- CenterOS下搭建Hadoop环境
检查防火墙状态 service iptables status 关闭防火墙 service iptables stop 查看防火墙开机启动状态 chkconfig iptables --list 关闭 ...
- 解决Windows x64bit环境下无法使用PLSQL Developer连接到Oracle DB中的问题
本文是原创文章,转载请注明出处: http://blog.csdn.net/msdnchina/article/details/46416455 解决Windows x64bit环境下无法使用PLSQ ...
- 剑指Offer:反转链表【24】
剑指Offer:反转链表[24] 题目描述 输入一个链表,反转链表后,输出新链表的表头. 解题分析 这道题我才发现我是属于那种真的笨,图都画出来了流程写不出来.看了别人的代码,总觉得自己差一步. 这也 ...
- hibernate属性配置
数据库中一个字段的默认值设为0,当用hibernate插入数据时,没有对该字段进行操作,结果该字段居然不是0,而是空.后来google了一下,发现应该在.hbm.xml文件中添加一些参数定义(示例中的 ...
- 收集Oracle数据库中的SQL基线信息(一)基础信息收集
Oracle数据库中的SQL基线信息,当数据库出现性能问题时,在业务无法提供相应业务信息时,通过对比SQL基线信息来查找SQL的变化. 查找数据库一天内运行次数大于5000次的sqlid select ...
- Codeforces Round #401 (Div. 2) D Cloud of Hashtags —— 字符串
题目链接:http://codeforces.com/contest/777/problem/D 题解: 题意:给出n行字符串,对其进行字典序剪辑.我自己的想法是正向剪辑的,即先对第一第二个字符串进行 ...
- (转)Java经典设计模式(2):七大结构型模式(附实例和详解)
原文出处: 小宝鸽 总体来说设计模式分为三大类:创建型模式.结构型模式和行为型模式. 博主的上一篇文章已经提到过创建型模式,此外该文章还有设计模式概况和设计模式的六大原则.设计模式的六大原则是设计模式 ...
- jmeter中的响应断言
断言就类似LoadRunner中的检查点.对上一个请求返回的信息,做字符串.数据包大小.HTML.XML.图片等做判断,确保返回的信息的准确性. jmeter的断言有好多,下面是一个响应断言 新建一个 ...
- hdu 1205 吃糖果(抽屉原理)
题意:N种糖果,不能把一样的放在一起吃,即第一次吃一种,下一次吃另一种. 思路:找到个数最多的糖果种类(最大的数目记作 ma,该糖果种类记为a),首先把这n个糖果放到n个抽屉里面,然后把剩余的N-1种 ...