#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
斐波那契堆
最新推荐文章于 2018-08-04 09:20:57 发布