838. 堆排序

摘要
Title: 838. 堆排序
Tag: 堆
Memory Limit: 64 MB
Time Limit: 1000 ms

Powered by:NEFU AB-IN

Link

838. 堆排序

  • 题意

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

  • 思路

    堆是一个完全二叉树(除了最后一层结点不满,其它结点皆非空)
    img

  • 代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    #include <iostream>
    #include <algorithm>

    using namespace std;

    const int N = 100010;

    int n, m;
    int h[N], cnt;

    void down(int u)
    {
    int t = u; //用t来表示三个点里最小的那个点
    if (u * 2 <= cnt && h[u * 2] < h[t]) t = u * 2; //如果左儿子小
    if (u * 2 + 1 <= cnt && h[u * 2 + 1] < h[t]) t = u * 2 + 1; //如果右儿子小
    if (u != t) // 如果不和u一样,就交换,继续递归
    {
    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]);
    cnt = n;

    for (int i = n / 2; i; i -- ) down(i); //O(n)级别的建树,在n/2往下沉即可

    while (m -- )
    {
    printf("%d ", h[1]);
    h[1] = h[cnt -- ];
    down(1);
    }

    puts("");

    return 0;
    }


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    '''
    Author: NEFU AB-IN
    Date: 2022-03-02 10:37:05
    FilePath: \ACM\Acwing\838.py
    LastEditTime: 2022-03-02 10:43:56
    '''
    import heapq

    n, m = map(int, input().split())

    a = list(map(int, input().split()))
    q = []

    for i in range(n):
    heapq.heappush(q, a[i])

    for i in range(m):
    print(heapq.heappop(q), end=" ")

使用搜索:谷歌必应百度