左式堆合并的实现

这是第一篇博客,相信是个不错的开始!
//define the leftist heap struct
typedef struct Leftist pLeftist;
struct Leftist{

	int element;
	pLeftist left, right;
	int npl;
};

//build the merged leftist heap and return it
pLeftist BuildHeap(LeftistQueue q){

	Leftist h1, h2;

	while(!IsEmpty(q)){
		h1 = Dequeue(q);
		if(IsEmpty(q))
			return h1;		//the leftist heap has been built
		h2 = Dequeue(q);

		Enqueue(q, Merge(h1, h2));	//enqueue the new merged leftist heap
	}

	return NULL;	//there is no leftist heap in queue
}

pLeftist Merge(Leftist h1, Leftist h2){

	if(!h1)
		return h2;
	if(!h2)
		return h1;	

	if(h1->element<h2->element)		//compare the element and choose the root
		return MergeHeap(h1, h2);
	else
		return MergeHeap(h2, h1);
}

pLeftist MergeHeap(Leftist h1, Leftist h2){

	if(!h1->left){
		h1->left = h2;		//single node
	}else{
		h1->right = Merge(h1->right, h2);
		if(h1->left->npl<h1->right->npl)	//make left child's npl >= right's
			SwapChl(h1);
		h1->npl = h1->right->npl+1;		//make the npl equalling its right child+1
	}

	return h1;	//return the root
}

左式堆而言,较于小根堆

1.合并速度快,O(n)

2.链表比数组带来更多的开销,并且多一个域(npl)

3.代码相对复杂,其实也不复杂


较于leftist heap,有个skew heap,每次合并都左右换一下,不需要(npl),如果数据是随机的,也是一个很不错的选择


有个同学说随机删除堆里的一个元素,这样的方法比较好:

将改点的值置为负无穷,然后冒泡到顶部,再删去顶部,将剩下的两个子树合并。


不过,堆似乎不是用来随机删除节点的。一般指删最小的,以前遇到过一个题目,在最小的三个元素中删除一个特定的,这样就可以在前三层找(应该是7个元素中),然后删,随机删除其中的任意节点得不偿失。

还有,删除任意节点,将其子树合并,合并获得的新树的根放回原来删除节点的位置,这样不是很合理吗,为何要冒泡到最顶部?



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值