AcWing
  • 首页
  • 活动
  • 题库
  • 竞赛
  • 应用
  • 更多
    • 题解
    • 分享
    • 商店
    • 问答
    • 吐槽
  • App
  • 登录/注册

AcWing 838. 堆排序

作者: 作者的头像   卷死你们QAQ ,  2023-03-15 20:33:42 ,  所有人可见 ,  阅读 12


0


#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 100010;

int a[N];//保存数组
int n, m;//n个点,求前m小
int r ;//堆得右边界
void down(int u)//调整函数
{
    //t记录最小点的编号
    int t = u;

    //有左儿子,并且左儿子比t节点的值小,更新t
    if(2 * u <= r && a[2 * u] < a[t]) t = 2 * u;

    //有右儿子,并且右儿子比t节点的值小,更新t
    if(2 * u + 1 <= r && a[2 * u + 1] < a[t]) t = 2 * u + 1;

    //如果待调整点不是最小的
    if(u != t)
    {
        //和最小的交换
        swap(a[u], a[t]);

        //递归处理
        down(t);
    }
}



int main()
{
    cin >> n >> m;
    r = n;//开始时,右边界是数组边界

    //读入数据
    for (int i = 1; i <= n; i ++ )
    {
        int x;
        cin >> a[i];
    }

    //从第一个非叶节点开始,从右到左,从下到上处理每个节点
   for(int i = n /2 ; i >= 1; i--)
   {
       down(i);
   }

    //输出m个最小值
    while (m -- )
    {
        //堆顶保存的最小值,输出堆顶
        cout << a[1] << " ";

        //将堆顶和右边界交换
        swap(a[1], a[r]);

        //右边界左移
        r--;

        //从新处理堆顶
        down(1);
    }
}

0 评论

你确定删除吗?
1024
x

© 2018-2023 AcWing 版权所有  |  京ICP备17053197号-1
用户协议  |  隐私政策  |  常见问题  |  联系我们
AcWing
请输入登录信息
更多登录方式: 微信图标 qq图标
请输入绑定的邮箱地址
请输入注册信息