数据结构 之 二叉堆
来源:互联网 发布:阿里云硬盘挂载 编辑:程序博客网 时间:2024/05/22 06:24
一、二叉堆简介:
二叉堆故名思议是一种特殊的堆,二叉堆具有堆的性质(父节点的键值总是大于或等于(小于或等于)任何一个子节点的键值),二叉堆又具有二叉树的性质(二叉堆是完全二叉树或者是近似完全二叉树)。当父节点的键值大于或等于(小于或等于)它的每一个子节点的键值时我们称它为最大堆(最小堆),或者是大根堆(小根堆)。
二叉堆多数是以数组作为它们底层元素的存储。
假如根节点在数组中的索引是1,那么根结点的左右子节点在数组中的位置是 2,3;存储在第n个位置的父节点,它的左右子节点在数组中的存储位置为2n与2n+1。
假如根节点在数组中的索引是0,那么根结点的左右子节点在数组中的位置是 1,2。存储在第n个位置的父节点,它的左右子节点在数组中的存储位置为2n+1与2n+2。
例如:
在这个图中,数组中的第一个元素(下标为0)就没有使用。
二、基本算法:
在二叉堆中,有两个基本的辅助算法:Sift-up(元素上移调整) 和 Sift-down(元素下移调整)。
下面分别给出其伪代码:
三、大根堆
下面直接贴出大根堆的实现代码:(在这个实现中,二叉堆中根结点在数组中的位置是从下标0开始的)
//最大堆的下滑调整void siftdown(int *heap,int start,int m) //m表示堆元素个数{ //注意数组下标是从0开始的 int i=start,j=2*i+1; int temp=heap[i]; while(j<=m) { if(j<m&&heap[j]<heap[j+1]) j++; //如果右结点大于左节点 if(temp>=heap[j]) break; else { heap[i]=heap[j]; i=j; j=2*j+1; } } heap[i]=temp;}//最大堆的上滑调整void siftup(int *heap,int start){ int j=start,i=(j-1)/2; int temp=heap[j]; //调整值 while(j>0) { if(heap[i]>=temp) break; //调整值小于等于其根植,结束 else { heap[j]=heap[i]; j=i; i=(i-1)/2; } } heap[j]=temp;}//向最大堆插入一个元素xbool insert(int *heap,int &n,int x) //将x插入到最大堆中{ //n表示堆元素个数 这里的n加一之后返回 heap[n]=x; siftup(heap,n); //从插入位置开始向上调整 n++; return true;}//删除堆顶元素bool remove(int *heap,int &n,int &x) //删除堆顶(最大元素)x返回堆顶元素{ //n表示堆元素个数 这里的n减一之后返回 x=heap[0]; heap[0]=heap[n-1]; //将堆中的最后一个元素转移到堆顶 n--; siftdown(heap,0,n); //从堆根位置开始从上向下调整 return true;}//创建一个最大堆void Creat_maxheap(int *arr,int n) //建立最大堆 //n表示堆元素个数{ int currentsize=n; //当前堆大小 int currentpos=(currentsize-2)/2; //开始调整位置 while(currentpos>=0) { siftdown(arr,currentpos,currentsize-1); currentpos--; }}//堆排序,利用大根堆从小到大排序数组void HeapSort(int *heap,int n){ for(int i=(n-2)/2;i>=0;i--) //将数组先转换成为堆(即建堆),这里是大根堆 siftdown(heap,i,n-1); for(int i=n-1;i>=1;i--) //排序 { swap(heap[0],heap[i]); siftdown(heap,0,i-1); }}其中需要注意的是堆排序,在上面的堆排序中,需要排序的数组作为参数直接传入方法中,在堆排序方法中会执行建堆过程。
下面给出一个堆排序的例子:
int num[8]={53,17,78,9,45,65,87,23}; int n=8; cout<<"排序前:"; for(int j=0;j<n;j++) cout<<num[j]<<" "; cout<<endl; HeapSort(num,n); cout<<"排序后:"; for(int j=0;j<n;j++) cout<<num[j]<<" "; cout<<endl;
从运行结果可以知道,利用最大堆进行排序的结果是非降序的。
四、小根堆
对照上文中的大根堆的实现代码,很快我们可以写成小根堆的实现代码如下:(注意:小根堆的根结点元素在数组中的位置也是从0开始的)
//最小堆的下滑调整void siftdown(int *heap,int start,int m) //m表示堆元素个数{ int i=start,j=2*i+1; int temp=heap[i]; while(j<=m) { if(j<m&&heap[j]>heap[j+1]) j++; if(temp<heap[j]) break; else { heap[i]=heap[j]; i=j; j=2*j+1; } } heap[i]=temp;}//最小堆的上滑调整void siftup(int *heap,int start){ int j=start,i=(j-1)/2; int temp=heap[j]; while(j>0) { if(heap[i]<=temp) break; else { heap[j]=heap[i]; j=i; i=(i-1)/2; } } heap[j]=temp;}//建立最小堆void Creat_minheap(int *arr,int n) //n表示堆元素个数{ int currentsize=n; //当前堆大小 int currentpos=(currentsize-2)/2; while(currentpos>=0) { siftdown(arr,currentpos,currentsize-1); currentpos--; }}//插入一个元素bool insert(int *heap,int &n,int x) //将x插入到最小堆中{ //n表示堆元素个数 这里的n加一之后返回 heap[n]=x; siftup(heap,n); n++; return true;}//删除堆顶元素bool remove(int *heap,int &n,int &x) //删除堆顶(最小元素)x返回堆顶元素{ //n表示堆元素个数 这里的n减一之后返回 x=heap[0]; heap[0]=heap[n-1]; n--; siftdown(heap,0,n); return true;}//堆排序,利用小根堆从大到小排序数组void HeapSort(int *heap,int n){ for(int i=(n-2)/2;i>=0;i--) //将数组(表)转换成为堆(建堆),这里是小根堆 siftdown(heap,i,n-1); for(int i=n-1;i>=0;i--) //排序 { swap(heap[0],heap[i]); siftdown(heap,0,i-1); }}
同样我们还是注意到这里的堆排序:
同样执行上面的一个堆排序例子:
int num[8]={53,17,78,9,45,65,87,23}; int n=8; cout<<"排序前:"; for(int j=0;j<n;j++) cout<<num[j]<<" "; cout<<endl; HeapSort(num,n); cout<<"排序后:"; for(int j=0;j<n;j++) cout<<num[j]<<" "; cout<<endl;
运行结果:
从运行结果可以知道,利用最小堆进行排序的结果是非升序的。
- 数据结构之二叉堆
- 数据结构 之 二叉堆
- 数据结构之二叉堆
- 数据结构之二叉堆
- 数据结构之(二叉)堆
- 数据结构学习之二叉堆
- 数据结构之二叉堆、堆排序
- 数据结构之二叉堆(构建堆,堆排序)-(七)
- 数据结构之二叉堆(构建堆,堆排序)
- 数据结构 之 二叉堆(Heap)
- 数据结构之优先队列(二叉堆)
- 数据结构基础 之 二叉堆 概念篇
- 数据结构之Binary Heap(二叉堆)
- 数据结构基础 之 二叉堆实现堆排序
- 【数据结构】二叉堆(堆)
- 数据结构 二叉堆 & 堆排序
- 数据结构-二叉堆
- 数据结构 - 二叉堆
- uva 658 - It's not a Bug, it's a Feature!(优先队列Dijkstra)
- Ext datefield 设置默认值
- 全排列递归算法
- 四旋翼飞行器的姿态解算小知识点
- Java 7之多线程第3篇 - 笔试、面试常见线程问题
- 数据结构 之 二叉堆
- Eclipse Hadoop开发 DFSLocation显示不完整
- hdu1261字串数(组合数--大数问题--包括加 ,乘,除)
- 模式识别中K-means算法实现
- 桥接模式
- 关于网络密码的可怕真相
- JVM如何理解Java泛型类
- HDU 1316 How Many Fibs? 大数
- iOS网络编程-解决iCloud文档存储过程中文档冲突问题