堆--优先队列
来源:互联网 发布:手机噪音检测软件 编辑:程序博客网 时间:2024/06/06 01:31
1.完全二叉树的一个父节点编号为k,那么他的左二子的编号为2*k,右二子节点的编号为2*k+1
2.如果已知儿子(左儿子或者右儿子)的编号为x,那么他的父节点的编号为x/2(取整除,就是计算机里的/)
3.一棵完全二叉树的高度为logN,即最多有logN层节点
4.最小堆是所有的父节点都比他的子节点小,最大堆是所有的父节点都比他的子节点大
5.像这样支持插入元素和寻找元素(最大值和最小值)的数据结构成为优先队列,如果使用普通队列,那么寻找最大元素就需要枚举整个队列,时间复杂度为O(n),时间复杂度比较高,如果是已经排好序的数组,那么插入一个元素需要移动大量的数据,时间复杂度依旧很高,而堆就是一种优先队列的实现,可以很好地解决这两种操作
6.堆经常被用来求一个数列中第K大的数,只需要建立一个大小为K的最小堆,堆顶就是第K大的数(举个例子,假设有事十个数,要求第3大的数,将前三个数建成最小堆,然后从第四个数开始,与堆顶元素比较,如果比堆顶元素大,则舍弃当前堆顶元素,而将这个新数作为堆顶,然后堆顶开始向下调整,如果比堆顶元素小,则不进入堆),同理如果求第K小的数,那么就建一个最大堆,这种方法的时间复杂度为O(NlogK)
<span style="font-size:18px;">//该算法用来把数从小到大排序#include<iostream>#include<queue>#include<stack>#include<cstdio>#include<string>#include<cstring>#include<algorithm>#define maxn 20#define inf 0x3f3f3f3fusing namespace std;int h[maxn];//用来存放堆的数组int n;//用来存储堆中元素的个数,也就是堆的大小//交换堆中两个元素的位置void swap(int i, int j){ int t=h[i]; h[i]=h[j]; h[j]=t; return;}void siftdown(int i)//从i开始向下调整{ int t,flag=1; while(i*2<=n && flag)//至少存在左儿子 { if(h[i*2]>h[i]) t=i*2; else t=i; if(i*2+1<=n)//如果存在右儿子 { if(h[i*2+1]>h[t]) t=i*2+1; } if(i!=t)//说明父节点不是最小的点 { swap(i,t);//交换父节点和比父节点大的子节点的位置 i=t;//更新为刚才交换的子节点的编号,方便继续向下调整 } else flag=0; } return;}void creat(){ for(int i=n/2;i>=1;i--)//从最后一个父节点开始向下调整 siftdown(i);}void heapsort(){ while(n>1) { swap(1,n); n--; siftdown(1); } return;}int main(){ int num; scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&h[i]); num=n; creat();//建堆 heapsort();//堆排序 printf("\n"); for(int i=1;i<=num;i++) printf("%d ",h[i]); printf("\n"); return 0; }/*输入数据 14 99 5 36 7 22 17 46 12 2 19 25 28 1 92 输出结果 1 2 5 7 12 17 19 22 25 28 36 46 92 99 */</span>
0 0
- 堆和优先队列
- 堆和优先队列
- 优先队列--二叉堆
- 优先队列--堆
- 二叉堆/优先队列
- 优先队列(堆)
- 优先队列实现堆
- 堆 优先队列
- 优先队列(堆)
- 优先队列与堆
- 优先队列(堆)
- poj3253 堆/优先队列
- 优先队列 - 堆
- 优先队列(堆)
- 优先队列(堆)
- 堆,优先队列
- 堆和优先队列
- 优先队列(堆)
- linux 服务器 创建vpn
- Activity的四种启动模式
- 装配Bean(三)
- 最近用到的命令
- C语言数组
- 堆--优先队列
- 404_根据uri拿到路径
- c++遍历数组
- 简单实例化解析安卓Thread线程
- 求π近似值
- 蒙特卡洛方法——玩具例子(1)圆周率
- C# Socket简单例子(服务器与客户端通信)
- 慎用git stash save -a
- 158象棋(13)