堆的建立

模板题:

#include<bits/stdc++.h>
using namespace std;
int n,m;
int a[11];
void update(int t)
{
    int i;
    while(t*2<=m)//当这个值还有子节点时进行下列循环    
    {
        if(a[t*2]<a[t])
        {
            i=2*t;
        }//如果左节点比他的父亲节点小,就应该更换左节点
        else i=t;
        if(t*2+1<=m)//如果右节点比左节点和父亲节点都小,则应该交换最小的
        {
            if(a[t*2+1]<a[i])
            {
                i=2*t+1;
            }
        }
        if(i!=t)//如果要更换的节点不是本身,则应该继续更新
        {
            int temp;
            temp=a[i];
            a[i]=a[t];
            a[t]=temp;
            t=i;
        }
        else break;

    }
}
void change()
{
    for(int i=m/2; i>=1; i--)
    {
        update(i);
    }//数组下标从m/2开始而不从m开始的原因是每一次是从父亲节点开始更新,然后将父亲节点和两个子节点进行比较
}
void tot()
{
    while(m>1)
    {
        int temp;
        temp=a[m];
        a[m]=a[1];
        a[1]=temp;
        update(m);
        m--;
    }
}
int main()
{
    ios::sync_with_stdio(false);
    cin>>n>>m;
    for(int i=1; i<=m; i++)
    {
        cin>>a[i];
    }//首先输入m个数,建立起初始堆
    int s=m;
    change();//对这一开始的m个数进行排序
    for(int i=m+1; i<=n; i++)
    {
        int x;
        cin>>x;
        if(x>a[1])
        {
            a[1]=x;
            change();
        }
    }
    tot();
    for(int i=1; i<=s; i++)
    {
        //cout<<" "<<a[i]<<" ";
        if(i==1)cout<<a[i];
        else cout<<" "<<a[i];
    }
    cout<<endl;
    return 0;
}
原文地址:https://www.cnblogs.com/letlifestop/p/10262964.html