配对堆
一种可并堆。
插入、合并复杂度为O(1),删除等操作的复杂度为均摊O(logn)。
优点:代码短,常数小。
配对堆的结构
用左儿子右兄弟的方式存树。
对每个结点,储存其右兄弟和最左端的儿子。
操作
merge(x,y):合并以x,y为根的两个配对堆。若x,y中有空树则返回非空树,否则将节点大的一棵树插入到小的树中(假设是小根堆)。
insert(x):插入一个点。直接merge(x,root)。
pop(x):删除堆顶元素。将根的所有子树从左到右两两合并,再从右到左依次合并。
代码实现
void ins(int x,int y)
{
a[y].r=a[x].a;
a[x].s=y;
}
void kill(int x)
{
a[root].s=a[x].r;
a[x].r=0;
}
int merge(int x)
{
if(!x||!y)
return x+y;
if(a[x].x>a[y].x)
swap(x,y);
ins(x,y);
return x;
}
void push(int x)
{
a[x].s=a[x].r=0;
root=merge(root,x);
}
int del()
{
if(!a[root].s)
return 0;
int x=a[root].s,y=a[x].r;
kill(x);
if(y)
kill(y);
return merge(merge(x,y),del());
}
int pop()
{
int r=a[root].x;
root=del();
return r;
}
int top()
{
return a[root].x;
}
题目推荐