堆 最小堆 最大堆 堆排序(小到大,大到小)
导航
1.了解什么是堆
2.如何创建最小堆,最大堆
3.新增值在堆中如何进行
4.完整的堆排序,升序和降序(两种方式)
————————————————————————————————————————
1.了解什么是堆
树型结构与图型结构的差别:
看是否有回路,无回路的是树型,有回路的是图型
满二叉树可以用数组进行存储,层次遍历顺序存储
设置其中父节点为k,儿子节点(左结点,右节点) 其中左节点 为2*k, 右节点为 2 * k+1
高度为log2^N
其中最典型的应用就是堆(也就是完全二叉树)
完全二叉树:
————————————————————————————————————————
2.如何将堆转化为最小堆,最大堆
有两层的直接用父结点来比较
三层的应该有倒数一层的右边节点开始依次往下
代码如下:(创建最小堆)
//这里用的是数组的方式存储堆
void siftdown(int i) //输入的是从i点往下找
{int t,flag=0; //flag用来表示无需再进行往下查找 //从i位置开始,判断是否有左孩子,并且没有找到最佳位置 while(i*2<=n&&flag==0){if(h[i]>h[i*2]) //比较父节点与左节点的大小 t = i*2;elset = i;if(i*2+1<=n){ //判断是否存在右孩子 if(h[t]>h[i*2+1]) //比较上一次父节点与左节点的最小值与右孩子大小 t = i*2+1;}if(t!=i){ //判断得到最小值是否为父节点,是的话flag标志1,不是的话交换,继续往下找 swap(t,i);i=t;}elseflag = 1;}
}
创建最大堆:只需要将父节点与左右孩子节点的判大小符号换一下就可以了
————————————————————————————————————————
3.新增值在堆中如何进行
先插入到堆中最后一个位置,在进行与父节点依次比对,找到最合适的位置
整个都用数组保存
代码:
//这里弄得是最小堆
void siftup(int i)
{int i,flag=0; //flag等于0表示当前子节点比父节点小 if(i==1) return; //如果为根节点直接返回 while(i!=1&&flag==0) { if(h[i]<h[i/2])swap(i,i/2);elseflag=1;i=i/2; //让子节点等于父节点的位置 }
}
————————————————————————————————————————
4.完整的堆排序,升序和降序
输入提示:
14
99 5 36 7 22 17 46 12 2 19 25 28 1 92
升序:
#include <stdio.h>
int h[101]; //用来存放堆的数组
int n; //存放堆的个数void swap(int x,int y)
{int t;t = h[x];h[x] = h[y];h[y] = t;
} void siftdown(int i)
{int t,flag=0; //flag用来表示无需再进行往下查找 //从i位置开始,判断是否有左孩子,并且没有找到最佳位置 while(i*2<=n&&flag==0){if(h[i]>h[i*2]) //比较父节点与左节点的大小 t = i*2;elset = i;if(i*2+1<=n){ //判断是否存在右孩子 if(h[t]>h[i*2+1]) //比较上一次父节点与左节点的最小值与右孩子大小 t = i*2+1;}if(t!=i){ //判断得到最小值是否为父节点,是的话flag标志1,不是的话交换,继续往下找 swap(t,i);i=t;}elseflag = 1;}
}void create()
{int i;for(i=n/2;i>=1;i--)siftdown(i);
}//用于返回最小值
int deletemax()
{int t;t=h[1];h[1]=h[n];n--; //删除一位siftdown(1); //进行最小堆return t;
}int main()
{int i,num;scanf("%d",&num);for(i=1;i<=num;i++)scanf("%d",&h[i]);n = num;//建立最小堆create();//删除顶部元素,接着将最后一个元素放入第一个顶点中,输出删除的元素for(i=1;i<=num;i++)printf("%d ",deletemax()); return 0;
}
其中deletemax()函数作用是每次返回最小值,并且将最后一个值移入到根节点再次进行最小堆,这样结束时数组中数据已不再是原来的。
若想用这样的来求降序也是可以的,只需要建立最大堆就行了,其余都一样
另一种方式来求解升序和降序
//之前创建的是最大堆
void headsort()
{while(n>1){swap(1,n); //将第一个与最后一个进行交换,此时最后一个点为最大值 n--; //下次建立最大堆不带上最后一个值 siftdown(1); //进行最大堆 }}
求解升序另一种方法完整:
#include <stdio.h>
int h[101]; //用来存放堆的数组
int n; //存放堆的个数void swap(int x,int y)
{int t;t = h[x];h[x] = h[y];h[y] = t;
} void siftdown(int i)
{int t,flag=0; //flag用来表示无需再进行往下查找 //从i位置开始,判断是否有左孩子,并且没有找到最佳位置 while(i*2<=n&&flag==0){if(h[i]<h[i*2]) //比较父节点与左节点的大小 t = i*2;elset = i;if(i*2+1<=n){ //判断是否存在右孩子 if(h[t]<h[i*2+1]) //比较上一次父节点与左节点的最小值与右孩子大小 t = i*2+1;}if(t!=i){ //判断得到最小值是否为父节点,是的话flag标志1,不是的话交换,继续往下找 swap(t,i);i=t;}elseflag = 1;}
}//开始创建堆
void create()
{int i;for(i=n/2;i>=1;i--)siftdown(i);
}//之前创建的是最大堆
void headsort()
{while(n>1){swap(1,n); //将第一个与最后一个进行交换,此时最后一个点为最大值 n--; //下次建立最大堆不带上最后一个值 siftdown(1); //进行最大堆 }}int main()
{int i,num;scanf("%d",&num);for(i=1;i<=num;i++)scanf("%d",&h[i]);n = num;//建立最小堆create();headsort(); //删除顶部元素,接着将最后一个元素放入第一个顶点中,输出删除的元素for(i=1;i<=num;i++)printf("%d ",h[i]); return 0;
}
堆 最小堆 最大堆 堆排序(小到大,大到小)相关推荐
- 【高性能定时器】时间堆(最小堆)
最小堆及其应用:时间堆 最小堆及其应用:时间堆 一. 堆 1. 概念 2. 最小堆的实现 3. 性质 4. 代码 二.时间堆 1. 概念简述 2. 实现细节 3. 代码 一. 堆 1. 概念 堆是一种 ...
- 利用最小堆找出10亿个数中最大的10000个数
最小堆 最小堆是一种完全二叉树,特点是根节点比两个子节点都小(或者根节点比子节点都大) 过程 先找10000个数构建最小堆 依次遍历10亿个数,如果比最小堆的最小值大,则替换这个最小值,并重新构建最小 ...
- 最小堆以及最小优先队列的实现
最小堆的实现 什么是最小堆 构建最小堆 MIN_HEAPITY的实现 MIN_HEAPIFY的时间复杂度分析 BUILD_MIN_HEAP的实现 建最小堆的时间复杂度分析 什么是最小堆 最小堆从逻辑上 ...
- Linux服务器开发,定时器方案红黑树,时间轮,最小堆
─────────────────────────────────────────────────────────────── ┌------------┐ │▉▉♥♥♥♥♥♥♥♥ 99% │ ♥❤ ...
- 后端开发【一大波有用知识】定时器方案红黑树,时间轮,最小堆
目录: 一.如何组织定时任务? 定时器收网络IO处理造成误差特别大,该怎么处理? 用何种数据机构存储定时器? 红黑树如何解决相同时间的key值的? 最小堆 时间轮 一个帮助理解单层级时间轮的例子 如何 ...
- java 最小堆_堆排序 最大堆 最小堆 Java 实现
堆 一点疑惑,堆排序是就地排序,所以空间复杂度是 O(1).但是,比如我有一个数组,建立一个最小堆,然后每次取出最小堆的顶点.建立最小堆需要额外空间? 不深究了,归并排序需要额外空间. 堆是完全二叉树 ...
- python实现最大堆,最小堆和堆排序
目录 0.什么是堆 1.最大堆的实现 2.最小堆的实现 3.堆排序 0.什么是堆 小堆和大堆分为如下图: 堆需要满足的条件: 1. 必须是二叉树,且必须是完全二叉树 2. 各个父节点必须大于或小于左右 ...
- 堆排序,为什么升序排列要建大堆,降序排列要建小堆
堆排序中用到了建立大小堆和向下调整的内容,对这些内容有些不了解的同学可以去补一补专门写堆的博客,方便更好的理解堆排序数据结构之堆(Heap),堆的相关操作,用堆模拟优先级队列. 如果把待排序序列分为未 ...
- 创建最大堆、最小堆、图解堆排序
优先级队列和堆 堆的存储方式 使用数组来保存二叉树,将二叉树的层序遍历结果按顺序放入数组中.这种方式只适合保存完全二叉树,因为非完全二叉树会浪费空间. 最大堆 满足任意节点的值都大于其子树中节点的值, ...
最新文章
- 脱壳 VMProtect 1.70.4
- 微软转型里程碑:云计算收入首次超过Windows业务
- centos7 中文乱码问题解决方法
- Androidstudio如何正确导入和移出jar包
- Redis 的缓存异常处理 —— 缓存雪崩、缓存击穿、缓存穿透
- PostgreSQL数据库、表空间、角色及用户
- Open Graph Protocol(开放内容协议)
- access vba代码大全_VBA编程在翻译中的应用
- phpstudy安装教程 2020
- 为什么会发生通货膨胀
- 111wqdqwdwedwedwdwededwedwe
- 详细介绍CoinList 2022 年夏季种子项目, web3概念最亮眼!
- linux安装redisDocker安装redis集群
- 【我命由我不由天】30多岁的大龄程序员,应该如何保持职场竞争力?
- hudson插件开发入门
- ArcView GIS 应用与开发技术(4)-地图投影
- 单招考试计算机ip不会看,单招考试“花样”多 不同维度测技能
- 台式计算机技术参数响应表,货物报价表及技术参数响应表.doc
- SSL 2331 洛谷 1717 信息学奥赛一本通 1373 鱼塘钓鱼#贪心#
- 图像水平投影和垂直投影,图像分割