文章目录

  • Question
  • Ideas
  • Code


Question

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

输入格式
第一行包含整数 n
和 m

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

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

数据范围
1≤m≤n≤105

1≤数列中元素≤109
输入样例:
5 3
4 5 1 3 2
输出样例:
1 2 3

Ideas

数组模拟堆实现堆排序_ci

Code

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

using namespace std;
const int N = 1e5 + 10;
int h[N]; // 用一个数组模拟堆

int cnt; // 堆中有多少元素
int n, m;

void down(int u){
    int t = u; // 父节点、两个子节点最小的值的下标
    if (2 * u <= cnt && h[2 * u] < h[t]) t = 2 * u;
    if (2 * u + 1 <= cnt && h[2 * u + 1] < h[t]) t = 2 * u + 1;
    if (t != u){
        swap(h[t], h[u]);
        down(t);
    }
    
}
int main(){
    cin >> n >> m;
    
    cnt = n;
    for (int i = 1; i <= n; i ++) cin >> h[i]; // 注意下标从1开始,为了防止左孩子下标(2*t)为0
    
    // O(N)时间复杂度建堆
    for (int i = n / 2; ~i ; i --) down(i);
    
    // 输出堆顶,最小值(小根堆)
    while (m --){
        cout << h[1] << ' ';
        // 删除堆顶
        h[1] = h[cnt];
        cnt --;
        down(1);
    }
    
    return 0;
}