堆排序[模板]

重点 堆的维护

拍桌!记得把循环的i从1开始!!!

(此处针对小根堆)每次将堆顶提出,即为当前最小值,再讲堆尾放到堆首,之后与左右节点比对,与其中较小的交换,直到重新成为小根堆。
附上父亲或儿子节点的计算方法:
用一个一维数组就可以装下一个完全二叉树,a[n]的父亲为a[n/2],儿子是a[n*2],a[n*2+1]
 #include<iostream>
    #include<cstdio>
    using namespace std;
    int n,x;
    int hp[20000],t,a[20000];
    void push(int x) {
        t++;
        int now=t;
        hp[now]=x;
        while(now>1) {
            if(hp[now]<hp[now/2]) {
                int ls=hp[now];
                hp[now]=hp[now/2];
                hp[now/2]=ls;
                now=now/2;
            } else break;
        }
    }
    int del() {
        int res=hp[1];
        hp[1]=hp[t];
        t--;
        int now=1;
        while(2*now<=t) {
            int tp=2*now;
            if(tp<t && hp[tp]>hp[tp+1]) tp++;
            if(hp[now]>hp[tp]) {
                int ls=hp[now];
                hp[now]=hp[tp];
                hp[tp]=ls;
                now=tp;
            } else break;
        }
        return res;
    }
    int main() {
        cin>>n;
        for(int i=0; i<n; i++) {
            cin>>x;
            push(x);
        }
    //    for(int i=1; i<=n; i++) {
    //        cout<<hp[i]<<endl;
    //    }
        for(int i=0;i<n;i++){
            a[i]=del();
        }
        for(int i=0;i<n;i++){
            cout<<a[i]<<" ";
        }
}

猜你喜欢

转载自blog.csdn.net/floatiy/article/details/78805831
今日推荐