zoukankan      html  css  js  c++  java
  • [OI学习笔记]配对堆

    配对堆是一种可并堆(可以将两个堆合并,且速度快),时间复杂度:

    合并merge:O(1)     插入push:O(1)     弹出pop:O(logn)

    配对堆不是二叉堆(我一开始不知道这个所以一直搞不懂)

    配对堆存树的方式不一样,如图,对于每个节点,有一条边指向最左边的儿子,一条指向他右边的兄弟

    和普通树的对比:(灵魂画图)(蓝色为普通方式,红色为做兄弟右儿子)

    以下均以大根堆为例

    合并:

    很简单,比较两树树根,将小的的根作为大的左儿子,然后将小的的根的右兄弟指为大的原来的左儿子

    如图:(根的值在点上)

    插入:

    直接将插入的点作为一个堆,然后和原堆合并

    弹出:

    把根断开

    从左到右依次两两合并,再从左到右依次合并,具体细节可参考代码

    代码:

    #include<cstdio>
    
    inline void swap(int &x,int &y){
        x^=y^=x^=y;
    }
    
    //大根堆 
    struct pairing_heap{
        struct node{
            int v,s,r;
        }tree[10010];
        int tot,root;
        pairing_heap(int _tot=0,int _root=0):tot(_tot),root(_root){}
        int Merge(int x,int y){//合并根为x,y的两棵树,返回根 
            if(!x||!y){root=x+y;return x+y;}//有一个是空树(为0)
            if(tree[x].v<tree[y].v)swap(x,y);
            tree[y].r=tree[x].s;tree[x].s=y;
            return root=x;
        }
        int Push(int x){
            tree[++tot].v=x;
            tree[tot].r=tree[tot].s=0;
            return Merge(root,tot);
        }
        void Del(int x){
            tree[root].s=tree[x].r;tree[x].r=0;
        }
        int Pop(){
            int x=tree[root].s,y=tree[x].r;
            if(x==0)return 0;
            Del(x);if(y)Del(y);
            return root=Merge(Merge(x,y),Pop());
        }
        int Top(){
            return tree[root].v;
        }
    };
    
    int main(){
        pairing_heap q;
        printf("input “0”for push,“1” for top,“2” for pop or “-1” for exit 
    ");
        while(1){
            int ques;
            scanf("%d",&ques);
            if(ques==0){
                int x;
                scanf("%d",&x);
                q.Push(x);
            }else if(ques==1){
                printf("%d
    ",q.Top());
            }else if(ques==2){
                q.Pop();
            }else if(ques==-1){
                break;
            }
        }
        return 0;
    } 
    本篇文章为SHINE_GEEK原创,转载请注明来源!
    written_by:SHINE_GEEK

    -------------------------------------
    签名:自己选的路,跪着也要走完;理想的实现,需要不懈奋斗!
    -------------------------------------
  • 相关阅读:
    封装aixos拦截器
    vue路由传参的三种基本方式
    vue里的路由钩子
    箭头函数特点
    webstorm激活码
    vue-cli2使用less
    vue-cli2使用rem适配
    XfZGkvBaeh
    python解析excel中图片+提取图片
    python解析谷歌在线表格链接,转化为数组形式,图片转化为链接
  • 原文地址:https://www.cnblogs.com/sjrb/p/10373313.html
Copyright © 2011-2022 走看看