二项堆

// binomial heap.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

template<typename keytype>
struct bh_node 
{
	struct bh_node<keytype> *child;
	struct bh_node<keytype> *parent;
	struct bh_node<keytype> *sibling;
	int degree;
	keytype key;
};

template<typename keytype>
class bin_heap
{
private:
	bh_node<keytype> *head;
public:
	bin_heap();
	~bin_heap();
	bin_heap *bin_heap_initialize();
	bool bin_heap_is_empty(){return head == NULL;}
	void bin_heap_clear();
	bin_heap *bin_heap_union(bin_heap *h1 , bin_heap *h2);
	bin_heap *bin_heap_insert(bh_node<keytype> *nd);
	bin_heap *bin_heap_insert(keytype key);
	const bh_node<keytype> *bin_heap_minimum() const;
	bh_node<keytype> *bin_heap_extract_min();
	bh_node<keytype> *bin_heap_decrease_key(bh_node<keytype> *nd , keytype key);
	bin_heap *bin_heap_delete(bh_node<keytype> *nd);
private:
	bin_heap *bin_heap_root_merge(bin_heap *h1 , bin_heap *h2);
	void bin_heap_node_link(bh_node<keytype> *chd , bh_node<keytype> *pnt);
	void bin_heap_node_destroy(bh_node<keytype> *nd);
};


template <typename keytype>
bin_heap<keytype>::bin_heap()
{
	bin_heap_initialize();
}

template <typename keytype>
bin_heap<keytype>::~bin_heap()
{
	bin_heap_clear();
}


template <typename keytype>
void bin_heap<keytype>::bin_heap_node_destroy(bh_node<keytype> *nd)
{
	bh_node<keytype> *cur = nd->child;
	if (cur)
	{
		while(cur)
		{
			bin_heap_node_destroy(cur);
			cur = cur->sibling;
		}
	}
	else
		delete cur;
	cur = NULL;
}


template <typename keytype>
void bin_heap<keytype>::bin_heap_clear()
{
	if (head == NULL)return;
	bh_node<keytype> *cur = head , *nxt;
	while(cur)
	{
		nxt = cur->sibling;
		bin_heap_node_destroy(cur);
		cur = nxt;
	}
	head = NULL;
}


template <typename keytype>
bin_heap<keytype> *bin_heap<keytype>::bin_heap_initialize()
{
	head = NULL;
	return this;
}

template <typename keytype>
const bh_node<keytype> *bin_heap<keytype>::bin_heap_minimum() const
{
	const bh_node<keytype> *rst, *pbh;
	if (head == NULL)
	{
		return NULL;
	}
	else
	{
		rst = head;
		pbh = rst->sibling;
	}
	while(pbh != NULL)
	{
		if (pbh->key < rst->key)rst = pbh;
		pbh = pbh->sibling;
	}
	return rst;
}


template<typename keytype>
bin_heap<keytype> *bin_heap<keytype>::bin_heap_root_merge(bin_heap *h1 , bin_heap *h2)
{
// 	if (!bin_heap_is_empty())bin_heap_clear();
	bin_heap<keytype> bh;
	bh.bin_heap_initialize();
	bh_node<keytype> *pbh,*ph1,*ph2;
	if (h1->head == NULL)
	{
		bh.head = h2->head;
		h2->head = NULL;
		this->head = bh.head;
		bh.head = NULL;
		return this;
	}
	else if (h2->head == NULL)
	{
		bh.head = h1->head;
		h1->head = NULL;
		this->head = bh.head;
		bh.head = NULL;
		return this;
	}
	else
	{
		ph1 = h1->head;
		ph2 = h2->head;
		if (ph1->degree < ph2->degree)
		{
			pbh = bh.head = ph1;
			h1->head = ph1->sibling;
			ph1 = ph1->sibling;
		}
		else
		{
			pbh = bh.head = ph2;
			h2->head = ph2->sibling;
			ph2 = ph2->sibling;
		}
	}
	while(ph1 != NULL && ph2 != NULL)
	{
		if (ph1->degree < ph2->degree)
		{
			pbh->sibling = ph1;
			h1->head = ph1->sibling;
			ph1 = ph1->sibling;
		}
		else
		{
			pbh->sibling = ph2;
			h2->head = ph2->sibling;
			ph2 = ph2->sibling;
		}
		pbh = pbh->sibling;
	}
	if (ph1 == NULL)
	{
		ph1 = ph2;
		h1 = h2;
	}
	while(ph1 != NULL)
	{
		pbh->sibling = ph1;
		h1->head = ph1->sibling;
		ph1 = ph1->sibling;
		pbh = pbh->sibling;
	}
	this->head = bh.head;
	bh.head = NULL;
	return this;
}

template<typename keytype>
void bin_heap<keytype>::bin_heap_node_link(bh_node<keytype> *chd , bh_node<keytype> *pnt)
{
	chd->parent = pnt;
	chd->sibling = pnt->child;
	pnt->child = chd;
	pnt->degree++;
}

template<typename keytype>
bin_heap<keytype> *bin_heap<keytype>::bin_heap_union(bin_heap *h1 , bin_heap *h2)
{
// 	if (!bin_heap_is_empty())bin_heap_clear();

	bin_heap<keytype> bh;
	bh.bin_heap_initialize();
	bh.bin_heap_root_merge(h1,h2);

	if (bh.head == NULL)return this;

	bh_node<keytype> *pre,*cur,*nxt;
	pre = NULL;
	cur = bh.head;
	nxt = cur->sibling;

	while(nxt != NULL)
	{
		if (cur->degree != nxt->degree || (nxt->sibling !=NULL && nxt->sibling->degree == cur->degree))
		{
			pre = cur;
			cur = nxt;
		}
		else if ( cur->key <= nxt->key)
		{
			cur->sibling = nxt->sibling;
			bin_heap_node_link(nxt , cur);
		}
		else 
		{
			if (pre == NULL)
			{
				bh.head = nxt;
			}
			else
			{
				pre->sibling = nxt;
			}
			bin_heap_node_link(cur,nxt);
			cur = nxt;
		}
		nxt = cur->sibling;
	}
	this->head = bh.head;
	bh.head = NULL;
	return this;
}


template<typename keytype>
bin_heap<keytype> *bin_heap<keytype>::bin_heap_insert(bh_node<keytype> *nd)
{
	bin_heap bh;
	bh.bin_heap_initialize();
	nd->parent = NULL;
	nd->child = NULL;
	nd->sibling = NULL;
	nd->degree = 0;
	bh.head = nd;
	this->bin_heap_union(this,&bh);
	return this;
}

template<typename keytype>
bin_heap<keytype> *bin_heap<keytype>::bin_heap_insert(keytype key)
{
	bh_node<keytype> *nd = new bh_node<keytype>;;
	nd->key = key;
	bin_heap bh;
	bh.bin_heap_initialize();
	nd->parent = NULL;
	nd->child = NULL;
	nd->sibling = NULL;
	nd->degree = 0;
	bh.head = nd;
	this->bin_heap_union(this,&bh);
	return this;
}


template<typename keytype>
bh_node<keytype> *bin_heap<keytype>::bin_heap_extract_min()
{
	bh_node<keytype> *mini = NULL, *mini_pre= NULL , *pbh = NULL, *pbh_pre= NULL;
	if (head == NULL)
	{
		return NULL;
	}
	else
	{
		mini = head;
		mini_pre = NULL;
		pbh_pre = mini;
		pbh = mini->sibling;
	}
	while(pbh != NULL)
	{
		if (pbh->key < mini->key)
		{
			mini = pbh;
			mini_pre = pbh_pre;
		}
		pbh_pre = pbh;
		pbh = pbh->sibling;
	}
	
	bin_heap bh;
	bh.bin_heap_initialize();

	bh_node<keytype> *chd = mini->child , *chd_nxt = NULL;
	if (chd != NULL)
	{
		chd_nxt = chd->sibling;
		bh.head = chd;
		chd->sibling = NULL;
		chd = chd_nxt;
	}
	while(chd != NULL)
	{
		chd_nxt = chd->sibling;
		chd->sibling = bh.head->sibling;
		chd->parent = NULL;
		bh.head = chd;
		chd = chd_nxt;
	}
	if (mini_pre == NULL)
	{
		this->head = bh.head;
		bh.head = NULL;
	}
	else
	{
		bin_heap_union(this , &bh);
	}
	return mini;
}

template<typename keytype>
bh_node<keytype> *bin_heap<keytype>::bin_heap_decrease_key(bh_node<keytype> *nd , keytype key)
{
	if (head == NULL)return NULL;
	if (key > nd->key)return NULL;
	nd->key = key;
	bh_node<keytype> *nd_pnt = nd->parent;
	while(nd_pnt != NULL && nd_pnt->key > nd->key)
	{
		keytype tmp = nd->key;
		nd->key = nd_pnt->key;
		nd_pnt->key = tmp;

		nd = nd_pnt;
		nd_pnt = nd_pnt->parent;
	}
	
	return nd;
}

template<typename keytype>
bin_heap<keytype> *bin_heap<keytype>::bin_heap_delete(bh_node<keytype> *nd)
{
	keytype minimum = INT_MIN;
	bin_heap_decrease_key(nd,minimum);
	bin_heap_extract_min();
	return this;
}

int _tmain(int argc, _TCHAR* argv[])
{
	bin_heap<int> testheap;
	bin_heap<int> testheap2;
	bin_heap<int> testheap3;
	testheap.bin_heap_insert(20);
	testheap.bin_heap_insert(14);
	testheap.bin_heap_insert(67);
	testheap.bin_heap_insert(4);
	testheap.bin_heap_insert(8);
	testheap.bin_heap_insert(16);
	testheap.bin_heap_insert(5);

	testheap2.bin_heap_insert(3);
	testheap2.bin_heap_insert(2);
	testheap2.bin_heap_insert(80);

	testheap3.bin_heap_union(&testheap,&testheap2);
	const bh_node<int> *mini = testheap3.bin_heap_minimum();
	testheap3.bin_heap_decrease_key(mini->child,1);
	mini = testheap3.bin_heap_minimum();

	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值