左偏树
用二叉堆实现优先队列是十分有效的,然而,有时候我们会遇到“合并两个堆”这样的问题,如果用二叉堆实现就只能启发式合并,复杂度为\(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);} //弹出最小元素

浙公网安备 33010602011771号