• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
香草味羊扒饭
博客园    首页    新随笔    联系   管理    订阅  订阅
838. 堆排序

输入一个长度为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



#include<iostream>
#include<algorithm>
using namespace std;
const int N = 1e5 + 10;
int n,m;
int h[N];
int size;
//u表示当前元素的堆的起始位置
void down(int u){
    int t = u;//t表示三个点的最小值
    //首先判断有没有左儿子
    //判断左儿子
    if(u * 2 <= size && h[u * 2] < h[t]) t = u * 2;
    //判断右儿子
    if(u * 2 + 1 <= size && h[u * 2 + 1] < h[t]) t = u * 2 + 1;
    
    //当u不等于t,说明u不是我们的最小值,然后把t换成最小值
    //所以需要将t和u的位置换一下,换成三个点中最小的
    if(u != t){
        //最小值和父元素交换
        swap(h[u],h[t]);
        
        //继续往下判断
        down(t);
    }
}

int main(){
    scanf("%d%d",&n,&m);
    for(int i = 1;i <= n;i++){
        scanf("%d",&h[i]);
    }
    
    size = n;
    //插入元素,一般的插入nlog(n),这里用折半插入
    for(int i = n/2;i;i--) down(i);//递推,错位相减,得出等比数列前n项和小于1,得出插入的复杂度为O(n)
    while(m -- ){
        printf("%d ",h[1]);
        h[1] = h[size];size --;
        
        down(1);
    }
    
    return 0;
}

  

 
posted on 2019-10-27 10:07  香草味羊扒饭  阅读(194)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3