斐波那契堆

#ifndef __FINBONACCI_HEAP_H__  
#define __FINBONACCI_HEAP_H__  
#include "stdlib.h"
#include "math.h"
#define ERROR0 printf("error at file %s line %d\n",__FILE__,__LINE__)  

// 定义一个求有符号的无穷大的宏    
#define SIGN_INFINITELY_GREAT(T) ((0x1<<8*sizeof(T)-1)-1)    
// 定义一个求有符号的无穷小的宏    
#define SIGN_INFINITELY_SMALL(T) (0x1<<(8*sizeof(T)-1))    
// 定义INT型的无穷大值    
#define INT_INFINITELY_GREATE SIGN_INFINITELY_GREAT(int)    
// 定义INT型的无穷小值    
#define INT_INFINITELY_SMALL SIGN_INFINITELY_SMALL(int)    

template <typename Key>  
struct fibo_node   
{  
	struct fibo_node* pnt;  
	struct fibo_node* chd;  
	struct fibo_node* l;  
	struct fibo_node* r;  
	Key key;  
	int deg;  
	bool mrk;  
	void *data;  
};  

template <typename Key>  
class fibo_heap  
{  
private:  
	fibo_node<Key> *_minH;  
	int _nH;  
private:  
	void exchange(fibo_node<Key> **n1 , fibo_node<Key> **n2);  
	void consolidate();  
	void cut(fibo_node<Key> *n , fibo_node<Key> *p);  
	void cascading_cut(fibo_node<Key> *n);  
public:  
	fibo_heap();  
	~fibo_heap();
	bool isEmpty(){return _minH == NULL;}
	fibo_heap *insert_node(fibo_node<Key> *nd);  
	fibo_heap *heap_union(fibo_heap* h1,fibo_heap *h2);  
	fibo_node<Key> *extract_min();  
	fibo_heap *decrease(fibo_node<Key> *nd,Key key);  
	fibo_heap *delete_node(fibo_node<Key>* nd);  
};  

template <typename Key>  
fibo_heap<Key>::fibo_heap()  
{  
	_minH = NULL;  
	_nH = 0;  
}

template <typename Key>
fibo_heap<Key>::~fibo_heap()
{
	_minH = NULL;
	_nH = 0;
};

template<typename Key>  
fibo_heap<Key> *fibo_heap<Key>::insert_node(fibo_node<Key> *nd)  
{  
	if (nd == NULL)  
	{  
		ERROR0;  
		return this;  
	}  
	nd->deg = 0 ;  
	nd->chd = NULL;  
	nd->mrk = false;  
	nd->pnt = NULL;  
	if (_minH == NULL)  
	{  
		_minH = nd;
		_minH->l = _minH;
		_minH->r = _minH;
		_nH = 1;  
	}  
	else  
	{  
		nd->l = _minH->l;  
		nd->r = _minH;  
		_minH->l->r = nd;  
		_minH->l = nd;  
		if (nd->key < _minH->key)  
		{  
			_minH = nd;  
		}  	
		_nH++;  
	}  
	return this;  
}  

template <typename Key>  
fibo_heap<Key> *fibo_heap<Key>::heap_union(fibo_heap<Key> *h1,fibo_heap<Key> *h2)  
{  
	fibo_node<Key> *tmp;  
	int tmpi;  
	if (h1->_minH == NULL)  
	{  
		if (h2->_minH == NULL)  
		{  
			this->_minH = NULL;  
			this->_nH = 0 ;   
			return this;  
		}  
		tmp = h2->_minH;  
		tmpi = h2->_nH;  
		h2->_minH = NULL;  
		h2->_nH = 0;  
		this->_minH = tmp;  
		this->_nH = tmpi;  
		return this;  
	}  
	else if (h2->_minH == NULL)  
	{  
		tmp = h1->_minH;  
		tmpi = h1->_nH;  
		h1->_minH = NULL;  
		h1->_nH = 0;  
		this->_minH = tmp;  
		this->_nH = tmpi;  
		return this;  
	}  
	h1->_minH->l->l = h2->_minH->l;  
	h2->_minH->l->r = h1->_minH->l;  
	h2->_minH->l = h1->_minH;  
	h1->_minH->r = h2->_minH;  
	h1->_nH += h2->_nH;  
	if (h1->_minH->key > h2->_minH->key)  
	{  
		tmp = h1->_minH;  
		h1->_minH = h2->_minH;  
		h2->_minH = tmp;  
	}  
	tmp = h1->_minH;  
	tmpi = h1->_nH;  
	h1->_minH = h2->_minH = NULL;  
	h1->_nH = h2->_nH = 0;  
	this->_minH = tmp;  
	this->_nH = tmpi;  
	return this;  
}  


template<typename Key>  
fibo_node<Key> *fibo_heap<Key>::extract_min()  
{  
	fibo_node<Key> *m = _minH;  
	if (m ==NULL)  
	{  
		ERROR0;  
		return NULL;  
	}  
	fibo_node<Key> *c = m->chd;
	if (c != NULL)  
	{  
		fibo_node<Key> *cn = c->l;  
		do  
		{
			c->pnt = NULL;  
			c->l = m->l;  
			c->r = m;  
			m->l->r = c;  
			m->l = c;  
			c = (cn == m->chd)?NULL:cn;//条件判断要改善
			cn = cn->l;
		}while(c);
	}  
	if (m->l == m)  
	{  
		_minH = NULL;
	}  
	else  
	{  
		_minH = m->r;  
		m->r->l = m->l;  
		m->l->r = m->r;  
		m->l = m->r = m->chd = NULL;  
		consolidate();  
	}  
	_nH--;  

	return m;  
}  
//如何exchange,交换了两个结点位置(保持结点指针与结点数据关联性不变以便于外部调用)以及调用他们的指针(用于交换)
template <typename Key>  
void fibo_heap<Key>::exchange(fibo_node<Key> **n1 , fibo_node<Key> **n2)  
{  
	if (n1 == NULL || n2 == NULL)  
	{  
		ERROR0;  
		return;  
	}
	fibo_node<Key> *_n1 = *n1;
	fibo_node<Key> *_n2 = *n2;
	if (_n1 == _n2)return;  
	fibo_node<Key> *t;
	t = _n2->chd;  
	_n2->chd = _n1->chd;  
	_n1->chd = t;  

	t = _n2->pnt;  
	_n2->pnt = _n1->pnt;  
	_n1->pnt = t;  

	t = _n1->l;
	_n1->l = _n2->l;
	_n2->l->r = _n1;
	_n2->l = t;
	t->r = _n2;

	t = _n1->r;
	_n1->r = _n2->r;
	_n2->r->l = _n1;
	_n2->r = t;
	t->l = _n2;

	t = *n1;
	*n1 = *n2;
	*n2 = t;
}  

template <typename Key>  
void fibo_heap<Key>::consolidate()  
{  
	//20.4 最大度数的界
	float goldratio = (sqrt(5.f) + 1) * 0.5f;
	int len = log((float)_nH)/log(goldratio) + 1;  
	fibo_node<Key> **arr = (fibo_node<Key> **)calloc(len,sizeof(fibo_node<Key> *));  
	fibo_node<Key> *m = _minH;
	fibo_node<Key> *e = _minH->r;
	do   
	{
		while(arr[m->deg] != NULL)  
		{  
			fibo_node<Key> *n = arr[m->deg];
			if (n->key < m->key)exchange(&n,&m);  

			{//heap-link  
				n->l->r = n->r;  
				n->r->l = n->l;  
				n->pnt = m;
				if (m->chd)
				{
					n->r = m->chd;  
					n->l = m->chd->l;  
					m->chd->l->r = n;  
					m->chd->l = n;  
				}
				else
				{
					m->chd = n;
					n->l = n;
					n->r = n;
				}
				n->mrk = false;  
			}  

			arr[m->deg] = NULL;  
			m->deg++;  
		}  
		arr[m->deg] = m; 
		if (m == e || m== m->l)break;//边界需要改善
		m = m->l;
	} while (1);
	m = NULL;
	for (int i = 0 ; i < len ; i++)  
	{  
		if (arr[i] != NULL)  
		{
			if (m == NULL)m = arr[i];
			else if (arr[i]->key < m->key)
			{
				m = arr[i];  
			}
		}  
	}  
	_minH = m;  
}  


template<typename Key>  
void fibo_heap<Key>::cut(fibo_node<Key> *n , fibo_node<Key> *p)  
{  
	if (n->l == n)  
	{  
		p->chd = NULL;  
	}  
	else  
	{  
		n->l->r = n->r;  
		n->r->l = n->l;  
		if (p->chd == n)  
			p->chd = n->l;  
	}  
	p->deg--;  
	n->pnt = NULL;  
	n->l = _minH->l;  
	n->r = _minH;  
	_minH->l->r = n;  
	_minH->l = n;  
	n->mrk = false;  
}  


template <typename Key>  
void fibo_heap<Key>::cascading_cut(fibo_node<Key> *n)  
{  
	fibo_node<Key> *p = n->pnt;  
	if (p != NULL)  
	{  
		if (n->mrk == false)  
		{  
			n->mrk = true;  
		}  
		else  
		{  
			cut(n,p);  
			cascading_cut(p);  
		}  
	}  
}  

template <typename Key>  
fibo_heap<Key> *fibo_heap<Key>::decrease(fibo_node<Key> *nd,Key key)  
{  
	if (key > nd->key)  
	{  
		ERROR0;  
		return this;  
	}  
	fibo_node<Key> *p = nd->pnt;  
	nd->key = key;  
	if (p !=NULL && nd->key < p->key)  
	{  
		cut(nd,p);  
		cascading_cut(p);  
	}  
	if (nd->key < _minH->key)  
	{  
		_minH = nd;  
	}  
	return this;  
}  

template <typename Key>  
fibo_heap<Key> *fibo_heap<Key>::delete_node(fibo_node<Key>* nd)  
{  
	decrease(nd,INT_INFINITELY_SMALL);  
	extract_min(nd);  
	return this;  
}  

#endif  




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值