[模板题][排序]堆排序
程序员文章站
2022-06-11 12:06:18
...
来源: 模板题
算法标签:堆排序,堆
题目描述
输入一个长度为n的整数数列,从小到大输出前m小的数。
输入格式
第一行包含整数n和m。
第二行包含n个整数,表示整数数列。
输出格式
共一行,包含m个整数,表示整数数列中前m小的数。
数据范围
1≤m≤n≤105,
1≤数列中元素≤109
输入样例:
5 3
4 5 1 3 2
输出样例:
1 2 3
堆
堆的基本操作
1.插入一个数字
2.求集合中最小值
3.删除最小值
4.删除任意一个元素
5.修改任意一个元素
思路
我们先理解堆的思路
形如叶子节点不可不满的完全二叉树
如图:
现在我们来针对这道题书写一下思路
如图:
1.建堆
2.利用小根堆和down操作m次输出a[1] (堆最小值)
AC代码
#include<iostream>
using namespace std;
const int N=1e5+10;
int a[N];
int n,m;
void down(int u)
{
int t=u;//新指针,指向子节点
if(2*u<=n&&a[2*u]<a[t])t=2*u;//左子节点判断
if(2*u+1<=n&&a[2*u+1]<a[t])t=2*u+1;//右子节点判断 这里不直接交换的原因是 左右两次指向判断直接将t指向了左右子节点中最小的值
if(t!=u)swap(a[u],a[t]),down(t);//如果确实小于,就交换位子,并递归子节点
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)cin>>a[i];
for(int i=n/2;i;i--)down(i);//将所有子节点的节点放导合适位子
while(m--)
{
cout<<a[1]<<" ";//输出a[1]
a[1]=a[n--];//因为a[1]输出过了,此时我们要删除a[1],a[1]被a[n]覆盖,a长度--
down(1);//将放导a[1]的原a[n]排序到合适位子
}
return 0;
}
上一篇: Struts2.1.8使用心得
下一篇: 家,不是讲理的地方