左偏树

用二叉堆实现优先队列是十分有效的,然而,有时候我们会遇到“合并两个堆”这样的问题,如果用二叉堆实现就只能启发式合并,复杂度为\(O(nlogn)\),相反,用左偏树实现的优先队列就能很好的解决这类问题,复杂度也不错。

(这里没有讲解)

代码:

struct Node{
 Node *l,*r; //左右儿子
 int v,dist; //节点值与距离
 Node(int v,Node* null):v(v),dist(0),l(null),r(null) {}
} *root,*null;

//---------------Leftist Tree------------------

Node *newnode(int k) {return new Node(k,null);}

Node *merge(Node *a,Node *b) //合并两棵左偏树
{
 if (a==null) return b;
 if (b==null) return a;

 if ((a->v)>(b->v)) swap(a,b);
 
 a->r=merge(a->r,b);
 if ((a->l->dist)<(a->r->dist)) swap(a->l,a->r);
 if (a->r==null) a->dist=0; else a->dist=a->r->dist+1;
 
 return a;
}

void init() {null=newnode(-1),null->dist=-1,root=null;} //初始化

int top() {return (root==null)?(-1):(root->v);} //取最小元素

void insert(int k) {root=merge(root,newnode(k));} //插入元素

void pop() {root=merge(root->l,root->r);} //弹出最小元素

posted @ 2017-02-20 15:47  Krew  阅读(112)  评论(0)    收藏  举报