avatar

算法-堆排序

堆排序

输入一个长度为n的整数数列,从小到大输出前m小的数。

输入格式

第一行包含整数n和m。

第二行包含n个整数,表示整数数列。

输出格式

共一行,包含m个整数,表示整数数列中前m小的数。

数据范围

1≤m≤n≤1051≤m≤n≤105,
1≤数列中元素≤1091≤数列中元素≤109

输入样例:

5 3
4 5 1 3 2

输出样例:

1 2 3

题解:

//堆
//堆是一个完全二叉树
//小跟堆:根节点是整个树里最小的值,每一个节点都小于等于自己的子节点
//左儿子是 2x; 右儿子是 2x+1
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1e5+10;
int n,m;
int a[N],sizes;
void down(int u)
{
    int t = u;
    if(u * 2 <= sizes && a[ u * 2 ] < a[t]) t = u*2;//左子树
    if(u * 2+1 <= sizes && a[u * 2 + 1] < a[t]) t = u * 2 + 1;//右子树
    if(u != t)
    {
        swap(a[u],a[t]);
        down(t);
    }
}
int main()
{
    cin >> n >> m;
    for(int i=1;i<=n;i++) cin >> a[i];
    sizes = n;

    for(int i = n /2;i;i--) down(i);//先找到初始的最小值

    while(m--)
    {
        cout <<  a[1] << " ";
        a[1] = a[sizes];
        sizes --;
        down(1);
    }
    return 0;
}

STL解法:

#include <iostream>
#include <queue>//使用优先队列
#include <vector>
#include <math.h>
using namespace std;
const int N = 1e5+10;
int main()
{
    cin.tie(0);
    ios::sync_with_stdio(false);
    int n,m;
    cin >> n >> m;
    int b[N];
    priority_queue<int> a;
    for(int i=1;i<=n;i++) cin >> b[i];//解决向堆里写入数列

    for(int i=1;i<=n;i++)  a.push(-b[i]);
    while(m--)
    {
        cout << abs(a.top()) << " ";//abs()输出绝对值
        a.pop();
    }

    return 0;
}
文章作者: wangzun233
文章链接: https://wangzun233.top/2020/04/17/%E7%AE%97%E6%B3%95-%E5%A0%86%E6%8E%92%E5%BA%8F/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 WangZun233