堆的定义:

最大树(最小树):每个结点的值都大于(小于)或等于其子结点(如果有的话)值的树。
最大堆(最小堆):最大(最小)的完全二叉树。

最大堆的抽象数据结构:

 class MaxHeap
{
private:
T* heapArray; //存放堆数据的数组
int CurrentSize;//当前堆中元素数目
int MaxSize; //堆中能容纳的最大元素数目
public:
MaxHeap(T* array,int num,int max);
virtual ~MaxHeap()
{
delete []heapArray;
}
void BuildHeap();
void Swap(int pos_x,int pos_y); //交换位置x与y的元素
bool IsLeaf(int pos) const; //如果是叶子结点,返回true
int LeftChild(int pos) const; //返回左孩子位置
int RightChild(int pos) const; //返回右孩子位置
int Parent(int pos) const; //返回父结点位置
bool Remove(int pos,T& node); //删除给定下标元素
void SiftDown(int left); //筛选法函数,参数left表示开始处理的数组下标
void SiftUp(int position); //从position向上开始调整,使序列成为堆
bool Insert(const T& newNode); //向堆中插入新元素newNode
T& RemoveMax(); //从堆顶删除最大值
void print(); //输出函数
};

下面是一些简单函数的实现:

 template<class T>
MaxHeap<T>::MaxHeap(T* array,int num,int max)
{
heapArray = array;
CurrentSize = num;
MaxSize = max;
}
template<class T>
void MaxHeap<T>::Swap(int pos_x,int pos_y)
{
T temp = heapArray[pos_x];
heapArray[pos_x] = heapArray[pos_y];
heapArray[pos_y] = temp;
}
template<class T>
bool MaxHeap<T>::IsLeaf(int pos) const
{
return (pos>=CurrentSize/)&&(pos<CurrentSize);
}
template<class T>
int MaxHeap<T>::LeftChild(int pos) const
{
return pos*+;
}
template<class T>
int MaxHeap<T>::RightChild(int pos) const
{
return pos*+;
}
template<class T>
int MaxHeap<T>::Parent(int pos) const
{
if(pos == )
return -;
return (pos-)/;
}

下面来看几个重要的操作的实现:

·堆的插入操作

(1)新元素添加到末尾(保持完全二叉树的性质);
(2)为了保持堆的性质,沿着其祖先的路径,自下而上依次比较和交换该结点与父结点的位置,直到重新满足堆的性质位置;
(3)在插入过程中,总是自下而上逐渐上升,最后停留在某个满足堆的性质的位置,故此过程又称为 “筛选”。

 template<class T>
bool MaxHeap<T>::Insert(const T& newNode)
{
if(CurrentSize == MaxSize)
return false;
heapArray[CurrentSize] = newNode;
SiftUp(CurrentSize);
CurrentSize++;
return true;
}

·建堆过程

(1)首先将所有关键码放到一维数组中,这时形成的完全二叉树并不具备堆的特性,但是仅包含叶子结点的子树已经是堆 (即在有n个结点的完全二叉树中,当i > [n/2]-1时,以关键码Ki为根的子树已经是堆。
(2)这时从含有内部结点数最少的子树(这种子树在完全二叉树的倒数第二层,此时i = [n/2]-1开始,从右至左依次调整。
(3)对这一层调整完成之后,继续对上一层进行同样的工作,直到整个过程到达树根时,整棵完全二叉树就成为一个堆了

 template<class T>
void MaxHeap<T>::BuildHeap()
{
for(int i = CurrentSize/-; i >= ; i--)
{
SiftDown(i);
}
}

·堆的删除操作

(1)把最末端结点填入删除产生的空位(保持完全二叉树的性质)
(2)为了保持堆的性质,比较当前结点和其父节点的大小来决定向上还是向下“筛选”,直到重新满足堆的性质位置

 template<class T>
bool MaxHeap<T>::Remove(int pos,T& node)
{
if(pos < || pos >= CurrentSize)
return false;
node = heapArray[pos];
heapArray[pos] = heapArray[--CurrentSize];
if(heapArray[Parent(pos)] < heapArray[pos])
{
SiftUp(pos);
}
else SiftDown(pos);
return true;
}

下面是删除堆顶元素的代码:

 template<class T>
T& MaxHeap<T>::RemoveMax()
{
if(CurrentSize == )
{
cout<<"Can't delete"<<endl;
exit();
}
else
{
Swap(,--CurrentSize);
if(CurrentSize>)
{
SiftDown();
}
return heapArray[CurrentSize];
}
}

下面是该类的核心代码:

向下筛选:

 template<class T>
void MaxHeap<T>::SiftDown(int left)
{
int i = left; //标识父结点
int j = LeftChild(i); //标识关键码较小的子结点
T temp = heapArray[i]; //保存父结点
while(j < CurrentSize) //筛选
{
if((j < CurrentSize-)&&(heapArray[j] < heapArray[j+]))
{//若有右结点,且大于左结点
j++; //则j指向右结点
}
if(temp < heapArray[j])
{//若父结点小于子结点的值则交换位置
heapArray[i] = heapArray[j];
i = j;
j = LeftChild(j);
}
else break;//找到恰当的位置,跳出循环
}
heapArray[i] = temp;
}

向上筛选:

 template<class T>
void MaxHeap<T>::SiftUp(int position)
{ //从position开始向上调整
int tempos = position;
T temp = heapArray[tempos];
while((tempos > )&&(temp > heapArray[Parent(tempos)]))
{
heapArray[tempos] = heapArray[Parent(tempos)];
tempos = Parent(tempos);
}
heapArray[tempos] = temp;
}

测试函数:

 int main()
{
int a[] = {,,,,,,,,,};
MaxHeap<int> S(a,,);
cout<<"构建最大堆:"<<endl;
S.BuildHeap();
S.print();
cout<<"插入元素10:"<<endl;
int newNode = ;
S.Insert(newNode);
S.print();
cout<<"删除堆顶元素:"<<endl;
S.RemoveMax();
S.print();
cout<<"删除pos = 1的元素:"<<endl;
int x;
S.Remove(,x);
cout<<"x = "<<x<<endl;
S.print();
return ;
}

测试结果:

[BinaryTree] 最大堆的类实现的更多相关文章

  1. Java类的继承与多态特性-入门笔记

    相信对于继承和多态的概念性我就不在怎么解释啦!不管你是.Net还是Java面向对象编程都是比不缺少一堂课~~Net如此Java亦也有同样的思想成分包含其中. 继承,多态,封装是Java面向对象的3大特 ...

  2. MVC+EF 理解和实现仓储模式和工作单元模式

    MVC+EF 理解和实现仓储模式和工作单元模式 原文:Understanding Repository and Unit of Work Pattern and Implementing Generi ...

  3. 携程Android App插件化和动态加载实践

    携程Android App的插件化和动态加载框架已上线半年,经历了初期的探索和持续的打磨优化,新框架和工程配置经受住了生产实践的考验.本文将详细介绍Android平台插件式开发和动态加载技术的原理和实 ...

  4. 省身 (zhuan)

    http://blog.csdn.net/marksinoberg/article/details/52419152 ***************************************** ...

  5. [百度空间] [转]DLL地狱及其解决方案

    DLL地狱及其解决方案 原作者:Ivan S Zapreev 译者:陆其明概要 本文将要介绍DLL的向后兼容性问题,也就是著名的“DLL Hell”问题.首先我会列出自己的研究结果,其中包括其它一些研 ...

  6. c#winform使用WebBrowser 大全[超长文转载]

    1.主要用途:使用户可以在窗体中导航网页. 2.注意:WebBrowser 控件会占用大量资源.使用完该控件后一定要调用 Dispose 方法,以便确保及时释放所有资源.必须在附加事件的同一线程上调用 ...

  7. (翻译)什么是Java的永久代(PermGen)内存泄漏

    http://www.codelast.com/?p=7248 转载请注明出处:http://www.codelast.com/ 本文是我对这篇文章的翻译:What is a PermGen leak ...

  8. My.Ioc 代码示例——使用条件绑定和元数据(可选)构建插件树

    本文旨在通过创建一棵插件树来演示条件绑定和元数据的用法. 说“插件树”也许不大妥当,因为在一般观念中,谈到插件树,我们很容易会想到 Winform/Wpf 中的菜单.举例来说,如果要在 Winform ...

  9. [欢度国庆]为什么我们今天还要学习和使用C++?(转载)

    在各种新的开发语言层出不穷的今天,在Java和C#大行其道今天,我们为什么还要学习和使用C++?现在学习C++将来有用吗?学习C++要花费那么多时间和精力,这一切都值得吗?现在学习C++有钱途吗? 这 ...

随机推荐

  1. jetson tx2 安装tensorflow

    官方的安装方法很简单: 可能会出现以下错误: 说的是dist-packages 权限不允许 consider using the "--user" to option or che ...

  2. javascript sorting/ v8 sorting

    https://github.com/mgechev/v8-sorting-test/tree/master/src/algorithms

  3. MVC PartialView 方式实现点击加载更多

    <table id="MovieListing"> </table><div> <button id="btnShowMore& ...

  4. Luogu2917_ [USACO08NOV]奶牛混合起来Mixed Up Cows_KEY

    题目传送门 看到数据范围就果断装压. 设f[i][j]表示i状态下最后一个数字为a[j]. code: #include <cstdio> using namespace std; ]; ...

  5. 网络流Edmonds-Karp算法入门

    今天自习课没事干,看书自学了一下网络流中的EK算法.(求最大流) 设s为源点,t为汇点,C为容量矩阵,F为流量矩阵,f为最大流量. 1.初始化F,f 2.用BFS在残量网络中找到一条从s到t的最短增广 ...

  6. 厦门Uber优步司机奖励政策(12月28日到1月3日)

    滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...

  7. dota2交换物品

    改成.bat 因为文件就可以 echo/>>c:/windows/system32/drivers/etc/hostsecho 111.230.82.224 steamcommunity. ...

  8. CentOS安装JMeter

    mkdir /usr/local/jmeter 新建jmeter目录 cd /usr/local/jmeter 进入jmeter目录 wget https://archive.apache.org/d ...

  9. Linux命令应用大词典-第36章 密码和证书管理

    36.1 pwdhash:密码哈希生成器 36.2 mkpasswd:生成应用于用户的新密码 36.3 keytool:密钥和证书管理工具 36.4 certutil:证书服务器管理工具 36.5 v ...

  10. 第四模块:网络编程进阶&数据库开发 第2章·MySQL数据库开发

    01-MySQL开篇 02-MySQL简单介绍 03-不同平台下安装MySQL 04-Windows平台MySQL密码设置与破解 05-Linux平台MySQL密码设置与破解 06-Mac平台MySQ ...