最大(小)堆 优先队列模板

本文介绍了最小(大)堆及其在优先队列中的应用,详细讲解了创建、调整、变更及输出等核心函数,包括`creat()`、`siftdown()`、`change()`和`dt()`。通过实例代码展示了如何实现堆排序,并对比了最大堆与最小堆的区别。
摘要由CSDN通过智能技术生成

本文参考于《啊哈!算法》,作者为纪磊。

最小(大)堆

众所周知 ,堆是一颗完全二叉树,而堆主要用于辅助程序进行排序等操作,一般不会独立作为考试内容。

著名应用就是优先队列了等时间复杂度为(nlogn) 的排序操作,而且是从输入后,就已经排完序。
话说我怎么就记不住(priority queue)呢?

首先建树函数creat();

从最后一个非叶节点的节点开始,依次向“上”进行向下调整。
因为完全二叉树的性质,所以从最后一个节点也就是下标为第n/2个节点开始向上搜索
代码:

void creat(){
   
	for(int i=n/2;i>=1;i--){
   
		siftdown(i);      //开始调整
	}
	return;
}
然后就看是调整函数siftdown(i);

先是判断扫描到的节点有没有子节点(左),如果有(左)先设置一个标记,转而判断是否有右子节点,如果有,与左节点比大小(因为是排序算法嘛)。判断完成后,如果发现标记与原来的节点下标不同了,就代表着有子节点并且如果比原节点大,就交换位置且让当前的位置维护成当前的标记。
代码:

void siftdown(int i){
   
	int t,f=0;  		//t就是那个标记
	while(i*2<=n && f==0){
   	//f代表着是否有子节点 没有退出则说明此节点为叶节点
		if(heap[i]>heap[2*i]){
     //原节点与左子节点判断大小
			t=i*2;               
		}else{
   
			t=i;                 
		}
		if(i*2+1<=n){
                    //是否有右节点
			if(heap[t]>heap[i*2+1]){
     //这里的heap[t]是左节点和原节点的最小值
				t=2*i+1;
			}
		}
		if(t!=i){
                                      //原节点有子节点且比他自身小
			change(t,i);                    //转换函数,要自己写一个新式的函数
			i=t;                                 //维护
		}else{
   
			f=1;                                //此节点为叶节点 退出
		}
	}
	return;
}

这段代码提到了change函数,所以change函数长这个样子:

change(x&
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值