摘要:二叉堆并不支持高效率的合并,因为这需要把一个数组拷贝到另外一个数组里面,这需要消耗O(N)的时间.实际上,所有高效支持合并的操作都是用指针来进行的.
左式堆也是一种二叉堆,它与普通二叉堆唯一的区别就是它是不平衡的二叉堆,实际上是非常不平衡.把一个节点的零路径(Npl)长定义为一个节点到一个没有两个儿子的节点的最短路径,因此具有一个儿子或者没有儿子的树的零路径长是0.而NULL节点的npl是-1.
注意,任意一节点的npl比它儿子的中最小npl多1.
左式堆的性质是:对于任意一个节点,左儿子的npl至少和右儿子一样大.
这个性质保证了右子树尽可能的短,所以将大多数工作都放在右子树上去做.
【1】基本数据结构
struct TreeNode
{
int Element;
int Npl;
LeftHeap Left;
LeftHeap Right;
};
【2】合并操作:
合并两个左式堆要保证不能破坏左式堆的性质.
{1}如果两个堆有一个是空的,则我们返回不为空的堆;
{2}否则,比较它们的根,将具有较大的根和较小根的右子树递归的合并.基础情况(根为空的时候)显然成立,如果中间步骤成立,那么该算法的正确性就可以被证明了.注意到该合并并不会破坏堆序(因为总是选取较小的根的右子树进行合并),这样较大的根就会被接在较小根的右子树上面。