左偏树讲解

来源:互联网 发布:扇贝和知米听力哪个好 编辑:程序博客网 时间:2024/04/29 17:21

左偏树,就是可并堆
效率:

- 左偏树 堆 插入 O(log n) O(log n) 删除 O(log n) O(log n) 合并 O(log n) O(nlog n) 查询 O(1) O(1)

合并不是一个级别的!!!
左偏树,具有堆的性质。
且,一直往右一定比一直往左的长度短,对于每一个节点都是这样。
事实上可以直接交换左右子树,并不需要比较长度,因为这样时间慢不了多少(事实上只是一两行的区别,可是空间不知道要大多少),可是我就是要记录左右长度。

#include<bits/stdc++.h>using namespace std;#define fr(i,a,b) for(int i=(a),_end_=(b);i<=_end_;i++)struct tree{    tree *l,*r,*f;    int v,sl,sr;    tree(){        l=r=f=NULL;        v=sl=sr=0;    }}*root,*k,*d;tree* merge(tree *x,tree *y){    if(x==NULL)return y;    if(y==NULL)return x;    if(x->v>y->v)        swap(x,y);    x->r=merge(x->r,y);    x->sr=x->r->sr+1;    if(x->sr>x->sl)    {        swap(x->l,x->r);        if(x->l)x->sl=s->l->sl+1;        if(s->r)x->sr=s->r->sr+1;    }    return x;}void insert(int x){    k=new tree;    k->v=x;    if(root==NULL)root=k;    else root=merge(root,k);}int top(){    if(root!=NULL)return root->v;    return -1;}void pop(){    if(root!=NULL)root=merge(root->l,root->r);}int main(){    root=NULL;    int n;    scanf("%d",&n);    fr(i,1,n){        int a;        scanf("%d",&a);        insert(a);    }    fr(i,1,n){        printf("%d ",top());        pop();    }    return 0;}
1 1
原创粉丝点击