堆--优先队列
来源:互联网 发布:网络投影仪怎么用 编辑:程序博客网 时间:2024/06/16 20:37
在进入主题之前, 先让我们来了解一下我们需要掌握的预备知识:树、二叉树。
有学习过算法的同学应该都听过图这个名词吧,树与图挺类似的,唯一的区别就是图是连同的,但树是不连通的,也就是任意两个节点之间有且只有一条路径。就像我们计算机文件夹的结构,如果我们要从一个文件夹到另一个文件夹,有且只有一条路径。
那二叉树又是什么呢?首先,二叉树是树,但它是特殊的数。二叉树的每一个节点最多只有两个子节点,左边的叫做左节点,右边的叫做右节点。二叉树又分为满二叉树与完全二叉树。满二叉树中每一个内部节点都具有两个儿子;如图:;完全二叉树除最高层外,其他各层节点数达到最大值, 同时;最高层只允许从右向左有连续若干缺节点;如图:,性状就类似与。二叉树为什么这么重要呢?二叉树具有什么样特殊的性质呢?笔者认为二叉树最重要的性质就是其父节点与子节点的关系了:如果父节点为 i 且其有子节点,则左子节点为 2*i ;右子节点为 (2*i+1);如果子节点为 i ;不论其是左子节点还是右子节点,其父节点为 (i/2)取整。根据这个性质;我们就可以用一维数组来存储一棵树了。
二叉树这个特殊的数据结构能给我们带来什么样的奇特功能呢?先让我们来看一张图:。不知道细心的你有没有发现什么玄机呢?是的,任何一个父节点都比它的子节点有小,这叫做最小二叉树;还有一种是任何一个父节点都比它的子节点的的,称为最大二叉树。如果我们这样安排数据,那会给我们什么样的方便呢?是的,如果我们这样做了,我们就可以准确的知道最小的数或最大的数在那,这样我们就不用遍历整个数组去找最大最小的数了。
下面我们讲一下怎样对二叉树进行操作。先讲插入:如果我们要插入一个数,我们先将这个数添加到数组的尾部,然后与其父节点比较,若小于父节点,就交换;交换后继续与对应的父节点比较,若还小,则继续交换,知道满足二叉树的性质。如果要删除最小的数呢?首先,我们把最后的一个数放在数组首部,让 其成为整个二叉树的根,然后在从根部一步步向下调整。那要怎么调整呢?首先,我们要让其先与左节点比较(因为若有子节点,则必有左节点);然后在与右节点比较;若都满足,则与最小的节点交换;重复次操作,直到满足二叉树的性质。
说了这么多,那我们要怎样实现一个二叉树呢?首先,我们先把所有的数据存进一个数组。在进行下面的操作之前,我们应知道:最后一个非叶节点为(n/2)。我们要把一颗杂乱的数整理成符合要求的二叉树;我们只需从最后一个非叶节点开始向下调整,直到根节点,则整理后的二叉树就是符合要求的二叉树。
全部代码如下:
#include<stdio.h>int h[101];int n;void swap(int x,int y){ //用于交换两个数int temp=h[x];h[x]=h[y];h[y]=temp;} void siftup(int i){ //用于插入一个数,向上调整int flag=0;if(i==1) return;while(i!=1&&flag==0){if(h[i]<h[i/2]){swap(i,i/2);}else flag=1;i=i/2;}}void siftdown(int i){ //向下调整int t,flag=0;while(i*2<=n&&flag==0){if(h[i]>h[2*i]){ t=2*i;}else t=i;if(i*2+1<=n){if(h[t]>h[2*i+1]) t=2*i+1;}if(t!=i){ swap(t,i); i=t; //继续循环,直至符合二叉树性质 }else flag=1;}}void creat(){ //创建二叉树for(int i=n/2;i>=1;i--){siftdown(i);}} int deletemin(){ //用于取出最小的元素 int t=h[1]; h[1]=h[n--]; siftdown(1); //重新调整二叉树 return t;}int main(){int num;scanf("%d",&num);n=num;for(int i=1;i<=n;i++){scanf("%d",&h[i]);} creat();for(int i=1;i<=num;i++){printf("%d ",deletemin());} return 0;}
- 堆和优先队列
- 堆和优先队列
- 优先队列--二叉堆
- 优先队列--堆
- 二叉堆/优先队列
- 优先队列(堆)
- 优先队列实现堆
- 堆 优先队列
- 优先队列(堆)
- 优先队列与堆
- 优先队列(堆)
- poj3253 堆/优先队列
- 优先队列 - 堆
- 优先队列(堆)
- 优先队列(堆)
- 堆,优先队列
- 堆和优先队列
- 优先队列(堆)
- 关于C++ const 的全面总结
- 深入理解jvm — 类加载篇
- Linux中fork,vfork和clone详解(区别与联系)
- 基于CentOS6.6为PHP安装redis和Memcahce的扩展
- mysql关键字讲解(join 、order by、group by、having、distinct)
- 堆--优先队列
- [BZOJ4542]大数
- Java线程同步和互斥
- hdu 5933 ArcSoft's Office Rearrangement(贪心)
- 摄像机标定03_标定过程(Camera Calibration)
- struts实现文件上传
- springmvc拦截器的问题
- C++中class与struct
- hdu1166敌兵布阵 树状数组&线段树 单点更新求区间和