博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
完全二叉堆
阅读量:6083 次
发布时间:2019-06-20

本文共 2980 字,大约阅读时间需要 9 分钟。

#include "Vector.hpp"//优先级队列PQ模板类template 
struct PQ{ virtual void insert(T) = 0; //按照比较器确定的优先级次序插入词条 virtual T getMax() = 0; //取出优先级最高的词条 virtual T delMax() = 0; //删除优先级最高的词条};#define InHeap(n, i) ( ((-1) < (i)) && ( (i)<(n) ) ) //判断PQ[i]是否合法#define Parent(i) ( (i-1) >> 1) //PQ[i]的父节点#define LastInternal(n) Parent(n-1) //最后一个内部节点(即末节点的父亲)#define LChild(x) (1 + ( (i) << 1)) //PQ[i]的左孩子#define RChild(x) ( (1 + (i)) << 1)//PQ[i]的右孩子#define ParentValid(i) (0 < i) //判断PQ[i]是否有父亲#define LChildValid(n, i) InHeap(n, LChild(i)) //判断PQ[i]是否有一个(左)孩子#define RChildValid(n, i) InHeap(n, RChild(i)) //判断PQ[i]是否有一个(右)孩子#define Bigger(PQ, i, j) ( lt(PQ[i], PQ[j]) ? j : i ) //取大者(等时前者优先)#define ProperParent(PQ, n, i) /*父子(至多)三者中的大者*/ \( RChildValid(n,i) ? Bigger(PQ, Bigger(PQ, i, LChild(i) ),RChild(i) ) : \( LChildValid(n, i) ? Bigger(PQ, i, LChild(i) ) : i\)\) //相等时父节点优先,如此可避免不必要的交换//完全二叉堆template
class PQ_ComplHeap : public PQ
, public Vector
{protected: Rank percolateDown(Rank n,Rank i); //下滤 Rank percolateUp(Rank i); //上滤 void heapify(Rank n); //Floyd建堆算法 public: PQ_ComplHeap() {} PQ_ComplHeap(T* A,Rank n) { this->copyFrom(A, 0, n); heapify(n); } void insert(T); //按照比较器确定的优先级次序,插入词条 T getMax();//读取优先级最高的词条 T delMax(); //删除优先级最高的词条 };//优先级最高的词条总是位于堆顶template
T PQ_ComplHeap
::getMax() { return this->_elem[0];}//将词条插入完全二叉堆中template
void PQ_ComplHeap
::insert(T e) { Vector
::insert(e); //首先将新词条接至向量末尾 percolateUp(this->_size - 1);//在对该词条实施上滤调整}//对向量中的第i个词条实施上滤操作,i < _sizetemplate
Rank PQ_ComplHeap
::percolateUp(Rank i) { while (ParentValid(i)) { //只要i有父亲(尚未抵达堆顶),则将i之父记作j Rank j = Parent(i); if ( lt(this->_elem[i], this->_elem[j])) { break; //一旦当前父子不再逆序,上滤旋即完成 } //否则,父子交换位置,并继续考察上一层 std::swap(this->_elem[i], this->_elem[j]); i = j; } return i; //返回上滤最终抵达的位置}//删除非空完全二叉堆中优先级最高的词条template
T PQ_ComplHeap
::delMax() { //摘除堆顶(首词条),代之以末词条 T maxElem = this->_elem[0]; this->_elem[0] = this->_elem[--this->_size]; percolateDown(this->_size, 0); //对新堆顶实施下滤 return maxElem; //返回此前备份的最大词条}//对向量前n个词条中的第i个实施下滤,i < ntemplate
Rank PQ_ComplHeap
::percolateDown(Rank n, Rank i) { Rank j; //i及其(至多两个)孩子中,勘为父者 while (i != (j = ProperParent(this->_elem, n, i))) { //只要i非j,则二者换位,并继续考察下降后的i std::swap(this->_elem[i], this->_elem[j]); i = j; } return i; //返回下滤抵达的位置(亦i亦j)}//Floyd建堆算法,O(n)时间template
void PQ_ComplHeap
::heapify(Rank n) { for (int i = LastInternal(n); InHeap(n, i); i--) { //自底向上,依次下滤各内部节点 percolateDown(n, i); }}template
void Vector
::heapSort(Rank lo, Rank hi) { //0 <= lo < hi <= size PQ_ComplHeap
H(this->_elem + lo, hi - lo); //将待排序区间建成一个完全二叉堆 while (! H.empty()) { //反复地摘除最大元并归入已排序的后缀,直至堆空 this->_elem[--hi] = H.delMax(); //等效于堆顶与末元素对换后下滤 } }

 

转载于:https://www.cnblogs.com/gkp307/p/9943792.html

你可能感兴趣的文章
CSS3让长单词与URL地址自动换行——word-wrap属性
查看>>
CodeForces 580B Kefa and Company
查看>>
开发规范浅谈
查看>>
Spark Streaming揭秘 Day29 深入理解Spark2.x中的Structured Streaming
查看>>
鼠标增强软件StrokeIt使用方法
查看>>
本地连接linux虚拟机的方法
查看>>
某公司面试java试题之【二】,看看吧,说不定就是你将要做的题
查看>>
BABOK - 企业分析(Enterprise Analysis)概要
查看>>
Linux 配置vnc,开启linux远程桌面
查看>>
NLog文章系列——如何优化日志性能
查看>>
Hadoop安装测试简单记录
查看>>
CentOS6.4关闭触控板
查看>>
ThreadPoolExecutor线程池运行机制分析-线程复用原理
查看>>
React Native 极光推送填坑(ios)
查看>>
Terratest:一个用于自动化基础设施测试的开源Go库
查看>>
修改Windows远程终端默认端口,让服务器更安全
查看>>
扩展器必须,SAS 2.0未必(SAS挺进中端存储系统之三)
查看>>
Eclipse遇到Initializing Java Tooling解决办法
查看>>
while((ch = getchar()) != '\n')
查看>>
好程序员web前端分享JS检查浏览器类型和版本
查看>>