[Acwing Algorithm Foundation] 2.8 Heap

down operation

  1. Swap the current node with the smallest value in the child nodes
  2. If the node at this time is not the minimum number, continue this operation
// down操作
void down(int u)
{
    
    
    int t = u;

    // 看看有没有左儿子,如果存在则t等于左儿子
    if (u * 2 <= s && h[u * 2] < h[t]) t = 2 * u;
    if (u * 2 + 1 <= s && h[u * 2 + 1] < h[t]) t = u * 2 + 1;    

    // t存的就是三个点里最小的节点编号
    // 如果根节点不是最小编号,那么再重复一遍这个操作
    if (u != t)
    {
    
    
        swap(h[u], h[t]);
        down(t);
    }
}

up operation

The up operation is relatively simple.
Each time it is compared with the parent node, if the parent node is larger than the current node, it is exchanged

// up操作
void up(int u)
{
    
    
    // 1. 有父节点
    // 2. 父节点比我当前这个节点要大
    while (u / 2 && h[u / 2] > h[u])
    {
    
    
        swap(h[u / 2], h[u]);
        u /= 2;
    }
}

full code

Example AcWing 838. Heap Sort

#include <iostream>

using namespace std;

const int N = 100010;

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

// down操作
void down(int u)
{
    
    
    int t = u;
    
    // 看看有没有左儿子,如果存在则t等于左儿子
    if (u * 2 <= s && h[u * 2] < h[t]) t = 2 * u;
    if (u * 2 + 1 <= s && h[u * 2 + 1] < h[t]) t = u * 2 + 1;    
    
    // t存的就是三个点里最小的节点编号
    // 如果根节点不是最小编号,那么再重复一遍这个操作
    if (u != t)
    {
    
    
        swap(h[u], h[t]);
        down(t);
    }
}


int main()
{
    
    
    scanf("%d%d", &n, &m);
    
    // 数组编号应该从1开始
    for (int i = 1; i <= n; ++i) scanf("%d", &h[i]);
    s = n;
    
    // 建堆 O(N)
    for (int i = n / 2; i; --i) down(i);
    
    // 输出堆顶并删除
    while (m--)
    {
    
    
        printf("%d ", h[1]);
        h[1] = h[s];
        s--;
        down(1);
    }
    
    puts("");
    
    return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326082187&siteId=291194637