二项堆是依赖于二项树而实现的,对于二项树,算法导论上讲解的很清楚,在此不再一一说明,首先还是说几个比较重要的概念。
什么是度:
注意。结点的度取决于T是有根树还是自由树。自由树中结点的度跟无向图一样,是相邻定点的个数
。而在有根树中,度指结点孩子的个数,结点的双亲不包括在内。。
有根树:一颗自由树,它有一个与其他不同的结点。这个特殊的顶点称为树的根,我们通常称
有根树的定点为结点。
根是树中唯一没有双亲的结点。
树的高度是根的高度,也等于结点中的最大深度。
有序树:是子女结点有序的有根树。
二项树是递归定义的有序树。
从上边我们可以看出,二项堆我们可以想象成二叉堆,它具有二叉堆的性质,但是二项堆是一组二项树实现的,所以这也是二项堆的差别之处,我们可以想象,二项堆的合并过程只需要o(lgn)时间就可以完成,但是二叉堆则需要o(n)时间内完成。所以,关于合并等我们倾向于二项堆的实现,导论上讲解的很清楚,关键是代码的实现过程,我是照着导论的伪代码敲得代码,可能有些地方不对,欢迎各位拍砖。。
代码奉上:
C++语言:
Codee#13364
//*********************************************************************
//实验题目:二项堆的相关的实现
//by dahsan1990
//完成状态:待完成
//完成时间:2010.9
//*********************************************************************
#include<iostream>
using namespace std;
#include<stdlib.h>
#define MAX 10000
#define MIN -10000
struct node
{
int data; //存储的数据
int degree; //当前节点的度数
struct node * lchild; //左孩子
struct node * sibling; //兄弟指针
struct node * parent; //父节点的指针
};
typedef struct node Dheap;
typedef Dheap * dheap;
dheap heap;
dheap BINOMIAL_heap_MINMUM( dheap H) //寻找最小关键字
{
dheap y = NULL;
dheap x = H;
int min = MIN;
while( x != NULL)
{
if( x -> data < min)
{
min = x -> data;
y = x;
}
x = x -> sibling; //找它的兄弟节点
}
return y;
}
dheap BINOMIAL_LINK( dheap y , dheap z) //连接两个树
{
y -> parent = z;
y -> sibling = z -> lchild;
z -> lchild = y;
z -> degree ++;
}
dheap BINOMIAL_HEAP_MERAGE( dheap h1 , dheap h2) //对两个二项树进行合并阶段
{
dheap x , y;
dheap i , j , h;
x = h1 , y = h2;
i = x;
j = y;
if( x == NULL && y == NULL)
{
printf( "NULL");
return NULL;
}
else
if( x == NULL && y != NULL)
{
return y;
}
else if( x != NULL && y == NULL)
{
return x;
}
if( x -> degree <= y -> degree)
{
h = x;
i = x -> sibling;
}
else
{
h = y;
j = y -> sibling;
}
while( i != NULL && j != NULL)
{
if( i -> degree <= j -> degree)
{
x -> sibling = i;
x = i;
i = i -> sibling;
}
else if( i -> degree > j -> degree)
{
x -> sibling = j;
x = j;
j = j -> sibling;
}
}
if( i != NULL)
{
x -> sibling = i;
}
if( j != NULL)
{
x -> sibling = j;
}
return h;
}
dheap MAKE_BINOMIAL_HEAP() //抽取根节点
{
heap = NULL;
heap = heap -> sibling; //抽取根节点
}
dheap BINOMIAL_HEAP_UNION( dheap h1 , dheap h2) //两个二项树的合并过程
{
dheap H;
H = MAKE_BINOMIAL_HEAP();
H = BINOMIAL_HEAP_MERAGE( h1 , h2);
if( H == NULL)
{
return H;
}
dheap prev_x = NULL;
dheap x = H;
dheap next_x = x -> sibling;
while( next_x != NULL)
{
if( x -> degree != next_x -> degree||( next_x -> sibling -> degree == x -> degree == next_x -> degree && next_x -> sibling != NULL))
{
prev_x = x;
x = next_x;
}
else if( x -> data <= next_x -> data)
{
x -> sibling = next_x -> sibling;
BINOMIAL_LINK( next_x , x);
}
else if( prev_x == NULL)
{
H = next_x;
}
else prev_x -> sibling = next_x;
BINOMIAL_LINK( x , next_x);
x = next_x;
next_x = x -> sibling;
}
return H;
}
dheap BINOMIAL_HEAO_INSERT( dheap H , int x) //向二项堆中插入一个数值
{
dheap w , H1;
w =( dheap) malloc( sizeof( Dheap));
H1 = MAKE_BINOMIAL_HEAP();
w -> data = x;
w -> parent = NULL;
w -> lchild = NULL;
w -> sibling = NULL;
w -> degree = 0;
H1 = w;
BINOMIAL_HEAP_UNION( H , H1);
return H;
}
dheap BINOMIAL_HEAP_DECREASE_KEY( dheap H , dheap x , int k)
{
if( k > x -> data)
{
printf( "erro,new key is greager than current key!!");
}
else
{
x -> data = k;
dheap y = x;
dheap z = y -> parent;
while( z != NULL && y -> data < z -> data)
{
int temp;
{
temp = y -> data;
y -> data = z -> data;
z -> data = temp;
}
y = z;
z = y -> parent;
}
}
}
dheap BINOMIAL_HEAP_DELEATE( dheap H , dheap x)
{
BINOMIAL_HEAP_DECREASE_KEY( H , x , MIN);
// BINOMIAL_HEAP_EXTRACT_MIN(H);
return H;
}
//实验题目:二项堆的相关的实现
//by dahsan1990
//完成状态:待完成
//完成时间:2010.9
//*********************************************************************
#include<iostream>
using namespace std;
#include<stdlib.h>
#define MAX 10000
#define MIN -10000
struct node
{
int data; //存储的数据
int degree; //当前节点的度数
struct node * lchild; //左孩子
struct node * sibling; //兄弟指针
struct node * parent; //父节点的指针
};
typedef struct node Dheap;
typedef Dheap * dheap;
dheap heap;
dheap BINOMIAL_heap_MINMUM( dheap H) //寻找最小关键字
{
dheap y = NULL;
dheap x = H;
int min = MIN;
while( x != NULL)
{
if( x -> data < min)
{
min = x -> data;
y = x;
}
x = x -> sibling; //找它的兄弟节点
}
return y;
}
dheap BINOMIAL_LINK( dheap y , dheap z) //连接两个树
{
y -> parent = z;
y -> sibling = z -> lchild;
z -> lchild = y;
z -> degree ++;
}
dheap BINOMIAL_HEAP_MERAGE( dheap h1 , dheap h2) //对两个二项树进行合并阶段
{
dheap x , y;
dheap i , j , h;
x = h1 , y = h2;
i = x;
j = y;
if( x == NULL && y == NULL)
{
printf( "NULL");
return NULL;
}
else
if( x == NULL && y != NULL)
{
return y;
}
else if( x != NULL && y == NULL)
{
return x;
}
if( x -> degree <= y -> degree)
{
h = x;
i = x -> sibling;
}
else
{
h = y;
j = y -> sibling;
}
while( i != NULL && j != NULL)
{
if( i -> degree <= j -> degree)
{
x -> sibling = i;
x = i;
i = i -> sibling;
}
else if( i -> degree > j -> degree)
{
x -> sibling = j;
x = j;
j = j -> sibling;
}
}
if( i != NULL)
{
x -> sibling = i;
}
if( j != NULL)
{
x -> sibling = j;
}
return h;
}
dheap MAKE_BINOMIAL_HEAP() //抽取根节点
{
heap = NULL;
heap = heap -> sibling; //抽取根节点
}
dheap BINOMIAL_HEAP_UNION( dheap h1 , dheap h2) //两个二项树的合并过程
{
dheap H;
H = MAKE_BINOMIAL_HEAP();
H = BINOMIAL_HEAP_MERAGE( h1 , h2);
if( H == NULL)
{
return H;
}
dheap prev_x = NULL;
dheap x = H;
dheap next_x = x -> sibling;
while( next_x != NULL)
{
if( x -> degree != next_x -> degree||( next_x -> sibling -> degree == x -> degree == next_x -> degree && next_x -> sibling != NULL))
{
prev_x = x;
x = next_x;
}
else if( x -> data <= next_x -> data)
{
x -> sibling = next_x -> sibling;
BINOMIAL_LINK( next_x , x);
}
else if( prev_x == NULL)
{
H = next_x;
}
else prev_x -> sibling = next_x;
BINOMIAL_LINK( x , next_x);
x = next_x;
next_x = x -> sibling;
}
return H;
}
dheap BINOMIAL_HEAO_INSERT( dheap H , int x) //向二项堆中插入一个数值
{
dheap w , H1;
w =( dheap) malloc( sizeof( Dheap));
H1 = MAKE_BINOMIAL_HEAP();
w -> data = x;
w -> parent = NULL;
w -> lchild = NULL;
w -> sibling = NULL;
w -> degree = 0;
H1 = w;
BINOMIAL_HEAP_UNION( H , H1);
return H;
}
dheap BINOMIAL_HEAP_DECREASE_KEY( dheap H , dheap x , int k)
{
if( k > x -> data)
{
printf( "erro,new key is greager than current key!!");
}
else
{
x -> data = k;
dheap y = x;
dheap z = y -> parent;
while( z != NULL && y -> data < z -> data)
{
int temp;
{
temp = y -> data;
y -> data = z -> data;
z -> data = temp;
}
y = z;
z = y -> parent;
}
}
}
dheap BINOMIAL_HEAP_DELEATE( dheap H , dheap x)
{
BINOMIAL_HEAP_DECREASE_KEY( H , x , MIN);
// BINOMIAL_HEAP_EXTRACT_MIN(H);
return H;
}