// 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;
}
二项堆
最新推荐文章于 2022-04-06 16:57:23 发布