二项堆

来源:互联网 发布:龙芯3a3000知乎 编辑:程序博客网 时间:2024/04/30 07:35
/**  * hp: min heap  * 790042744@qq.com  * 2012/2/11  */#ifndef BINOMIALHEAP_H#define BINOMIALHEAP_H#include <iostream>#include <stack>using std::stack;using std::cout;using std::endl;template< typename KeyType, typename ValueClass >class BinomialHeap;template< typename KeyType, typename ValueClass >class BinomialHeapNode{private:KeyType key;ValueClass value;int degree;BinomialHeapNode * parent;BinomialHeapNode * child;BinomialHeapNode * sibling;public:BinomialHeapNode(): parent(NULL), child(NULL), sibling(NULL) { degree = 0; }BinomialHeapNode( KeyType key, ValueClass value ): parent(NULL), child(NULL), sibling(NULL){degree = 0;parent = child = sibling = NULL;this->key = key;this->value = value;}~BinomialHeapNode() {};//const &const KeyType & GetConstKey() { return key; }const ValueClass & GetConstValue() { return value; }friend BinomialHeap<KeyType, ValueClass>;};template< typename KeyType, typename ValueClass >class BinomialHeap{public:typedef BinomialHeapNode<KeyType, ValueClass> BNode;typedef BinomialHeapNode<KeyType, ValueClass>* PBNode;private:PBNode head;public:BinomialHeap(): head(NULL) {}~BinomialHeap();PBNode Minimum();//值传参数也不行,原来的链表最终多是会被销毁的void Union( BinomialHeap * pHeap );void Insert( KeyType key, ValueClass value );void ExtractMinimum();bool DecreaseKey( PBNode pnode, KeyType key);     //should be privatevoid Delete( PBNode pnode );  //shoudl be private//just for testvoid PrintTree(); private:void __union( PBNode pnode );void __link( PBNode ar, PBNode br );//merging root table with pHeap, and pHeap heap would be destroyvoid __merge( PBNode pHeap );inline void __exchangeKeyValue( PBNode pnode1, PBNode pnode2 );void __clear( PBNode pnode );};///////////////////////////////////////////////////////////////////////////////////////////////////////////template< typename KeyType, typename ValueClass >BinomialHeap<KeyType, ValueClass>::~BinomialHeap() {if ( NULL != head )__clear( head );}template< typename KeyType, typename ValueClass >typename BinomialHeap<KeyType, ValueClass>::PBNode BinomialHeap<KeyType, ValueClass>::Minimum(){if ( NULL == head )return NULL;PBNode min, p;min = head;p = head->sibling;while ( NULL != p ){if ( p->key < min->key ){min = p;}p = p->sibling;}return min;}template< typename KeyType, typename ValueClass >void BinomialHeap<KeyType, ValueClass>::Union( BinomialHeap * pHeap ){__union( pHeap->head );pHeap->head = NULL;}template< typename KeyType, typename ValueClass >void BinomialHeap<KeyType, ValueClass>::Insert( KeyType key, ValueClass value ){PBNode  pnode = new BNode(key, value);__union( pnode );}template< typename KeyType, typename ValueClass >void BinomialHeap<KeyType, ValueClass>::ExtractMinimum(){if ( NULL == head )return;PBNode min, prev, pnode, next, newHead;min = head;prev = NULL;pnode = head;while ( NULL != pnode->sibling ){if ( pnode->sibling->key < min->key ){prev = pnode;min = pnode->sibling;}pnode = pnode->sibling;}if ( NULL != prev )prev->sibling = min->sibling;elsehead = min->sibling;pnode = min->child;min->child = NULL;min->sibling = NULL;newHead = NULL;while ( NULL != pnode ){next = pnode->sibling;pnode->sibling = newHead;pnode->parent = NULL;newHead = pnode;pnode = next;}__union( newHead );}template< typename KeyType, typename ValueClass >bool BinomialHeap<KeyType, ValueClass>::DecreaseKey( PBNode pnode, KeyType key){if ( key > pnode->key )return false;PBNode parent;pnode->key = key;parent = pnode->parent;while ( NULL != parent && parent->key > pnode->key ){//exchange key and data__exchangeKeyValue( pnode, parent );pnode = parent;parent = parent->parent;}return true;}template< typename KeyType, typename ValueClass >void BinomialHeap<KeyType, ValueClass>::Delete( PBNode pnode ){PBNode a, pa, next, newHead;a = pnode;pa = a->parent;while ( NULL != pa ){a->key = pa->key;a->value = pa->value;a = pa;pa = pa->parent;}//实际删除的是某棵二项树的根节点if ( head == a ){head = a->sibling;}else {//find previous node of a! Deleting a.for ( pa = head; pa->sibling != a; pa = pa->sibling );pa->sibling = a->sibling;}a->sibling = NULL;pa = a->child;a->child = NULL;delete a;newHead = NULL;while ( NULL != pa ){next = pa->sibling;pa->sibling = newHead;pa->parent = NULL;newHead = pa;pa = next;}__union( newHead );}//just for testtemplate< typename KeyType, typename ValueClass >void BinomialHeap<KeyType, ValueClass>::PrintTree(){if ( NULL == head )return;stack<PBNode> st;PBNode p = head;while ( p ){st.push(p);cout << p->key << ' ';p = p->child;}while ( !st.empty() ){p = st.top();st.pop();if ( p->sibling ){p = p->sibling;while ( p ){st.push(p);cout << p->key << ' ';p = p->child;}}}}///////////////////////////////////////////////////////////////////////////////////////////////////////////////////private:template< typename KeyType, typename ValueClass >void BinomialHeap<KeyType, ValueClass>::__union( PBNode tmphead ){//merging its root table with pHeap's!__merge( tmphead );if ( NULL == head )return;PBNode prev, pnode, next;prev = NULL;pnode = head;next = head->sibling;while ( NULL != next ){if ( pnode->degree != next->degree ||//case 1( NULL != next->sibling && next->degree == next->sibling->degree ) )//case 2{prev = pnode;pnode = next;}//pnode->degree == next->degreeelse if ( pnode->key <= next->key )//case 3{pnode->sibling = next->sibling;__link( next, pnode );}else {//case 4if ( NULL == prev )head = next;elseprev->sibling = next;__link( pnode, next );pnode = next;}next = pnode->sibling;}}// make ar heap as br's child!template< typename KeyType, typename ValueClass >void BinomialHeap<KeyType, ValueClass>::__link( PBNode ar, PBNode br ){ar->parent = br;ar->sibling = br->child;br->child = ar;++ br->degree;}template< typename KeyType, typename ValueClass >void BinomialHeap<KeyType, ValueClass>::__merge( PBNode pnode ){PBNode finalHead, pnode1, pnode2, tmp, p;pnode1 = head;pnode2 = pnode;p = finalHead = NULL;while ( NULL != pnode1 && NULL != pnode2 ){if ( pnode1->degree < pnode2->degree ){tmp = pnode1;pnode1 = pnode1->sibling;}else {tmp = pnode2;pnode2 = pnode2->sibling;}if ( NULL == finalHead )p = finalHead = tmp;else {p->sibling = tmp;p = tmp;}}if ( NULL == finalHead )finalHead = ( NULL == pnode1 ) ? pnode2 : pnode1;elsep->sibling = ( NULL == pnode1 ) ? pnode2 : pnode1;head = finalHead;}template< typename KeyType, typename ValueClass >void BinomialHeap<KeyType, ValueClass>::__exchangeKeyValue( PBNode pnode1, PBNode pnode2 ){KeyType tmpkey;ValueClass tmpvalue;tmpkey = pnode1->key;pnode1->key = pnode2->key;pnode2->key = tmpkey;tmpvalue = pnode1->value;pnode1->value = pnode2->value;pnode2->value = tmpvalue;}template< typename KeyType, typename ValueClass >void BinomialHeap<KeyType, ValueClass>::__clear( PBNode pnode ){PBNode child, sibling;child = pnode->child;sibling = pnode->sibling;delete pnode;if ( NULL != child )__clear( child );if ( NULL != sibling )__clear( sibling );}#endif


原创粉丝点击