#include <stdio.h>
#include <stdlib.h>
#define SUCCESS 1
#define FAIL 0
struct bheap
{
struct bheap* parent;
long key;
int degree;
struct bheap* child;
struct bheap* sibling;
};
typedef struct bheap bheap_node;
typedef struct bheap bheap_head;
void print(const int array[], int size);
bheap_node* creat_bheap_node();
void delete_bheap(bheap_head* head);
bheap_head* insert_bheap_node(bheap_head* head, bheap_node* node);
bheap_head* union_bheap(bheap_head* head1,bheap_head* head2);
bheap_head* merge_bheap(bheap_head* head1,bheap_head* head2);
void print_heap(bheap_head* head);
bheap_head* link_bheap(bheap_head* head1, bheap_head* head2);
bheap_node* get_biggest_bheap_node(bheap_head* head);
bheap_head* fetch_biggest_bheap_node(bheap_head* head);
void desrease_bheap_node_key(bheap_node* node, long new_key);
bheap_head* deleteb_bheap_node(bheap_head* head, bheap_node* del_node);
void print(const int array[], int size)
{
int index = 0;
while(index < size)
{
printf("%d ",array[index]);
index++;
}
printf("\n");
}
bheap_node* creat_bheap_node()
{
bheap_node* node = (bheap_node*)malloc(sizeof(bheap_node));
if(NULL != node)
{
node->parent = NULL;
node->key = 0;
node->degree = 0;
node->child = NULL;
node->sibling = NULL;
}
return node;
}
void delete_bheap(bheap_head* head)
{
bheap_node* node = head;
if(NULL == head)
return ;
do
{
if(NULL != head->child)//Child
{
node = head->child;
head->child = NULL;
head = node;
}
else if(NULL == head->child)//No Child
{
if(NULL != head->sibling)//Sibling
{
node = head->sibling;
}
else//No Sibling
node = head->parent;
free(head);
head = node;
}
}while((NULL != head->child)||(NULL != head->sibling) || (NULL != head->parent));
free(head);
}
bheap_head* insert_bheap_node(bheap_head* head, bheap_node* node)
{
return union_bheap(head,node);
}
bheap_head* union_bheap(bheap_head* head1,bheap_head* head2)
{
bheap_head* head;
bheap_head* pre_node;
bheap_head* curr_node;
bheap_head* next_node;
head = merge_bheap(head1, head2);
if(NULL == head)
return NULL;
pre_node = NULL;
curr_node = head;
next_node = head->sibling;
while(NULL != next_node)
{
if((curr_node->degree != next_node->degree) || ((NULL != next_node->sibling)&&(next_node->sibling->degree == curr_node->degree)))
{
pre_node = curr_node;
curr_node = next_node;
}
else if(curr_node->key > next_node->key)
{
curr_node->sibling = next_node->sibling;
curr_node = link_bheap(next_node, curr_node);
}
else if(curr_node->key <= next_node->key)
{
if(NULL == pre_node)
head = next_node;
else
pre_node->sibling = next_node;
next_node = link_bheap(curr_node,next_node);
curr_node = next_node;
}
next_node = curr_node->sibling;
}
return head;
}
bheap_head* merge_bheap(bheap_head* head1,bheap_head* head2)
{
bheap_head* head;
bheap_head* node;
bheap_head* smaller_node;
bheap_head* bigger_node;
int index = 0;
while((NULL != head1) && (NULL != head2))
{
if(head1->degree == head2->degree)
{
if(head1->key <= head2->key)
{
smaller_node = head1;
bigger_node = head2;
}
else
{
smaller_node = head2;
bigger_node = head1;
}
head1 = head1->sibling;
head2 = head2->sibling;
smaller_node->sibling = bigger_node;
}
else if(head1->degree > head2->degree)
{
bigger_node = smaller_node = head2;
head2 = head2->sibling;
}
else
{
bigger_node = smaller_node = head1;
head1 = head1->sibling;
}
if(0 == index)
head = smaller_node;
else
node->sibling = smaller_node;
node = bigger_node;
index++;
}
if(NULL == head1)
{
if(0 == index)
head = head2;
else
node->sibling = head2;
}
else//NULL == head2
{
if(0 == index)
head = head1;
else
node->sibling = head1;
}
return head;
}
void print_heap(bheap_head* head)
{
bheap_node* node;
int ret_parent = 0;
if(NULL == head)
{
printf("bheap: NULL\n");
return ;
}
node = head;
do
{
if((0 == ret_parent) && (NULL != node->child))
{
node = node->child;
}
else if((0 == ret_parent) && (NULL == node->child))
{
printf("Node key: %ld; degree: %d\n", node->key,node->degree);
if(NULL != node->sibling)
{
node = node->sibling;
ret_parent = 0;
}
else
{
node = node->parent;
if(NULL == node)
return;
ret_parent = 1;
}
}
else if(1 == ret_parent)
{
printf("Node key: %ld; degree: %d\n", node->key,node->degree);
if(NULL != node->sibling)
{
node = node->sibling;
ret_parent = 0;
}
else
{
node = node->parent;
ret_parent = 1;
}
}
}while((ret_parent == 0) || (NULL != node->sibling) || (NULL != node->parent));
printf("Node key: %ld; degree: %d\n", node->key,node->degree);
}
bheap_head* link_bheap(bheap_head* head1, bheap_head* head2)
{
head1->parent = head2;
head1->sibling = head2->child;
head2->child = head1;
head2->degree ++;
return head2;
}
bheap_node* get_biggest_bheap_node(bheap_head* head)
{
bheap_node* node = head;
long max;
bheap_node* biggest_node;
if(NULL == head)
return NULL;
max = head->key;
while(NULL != node)
{
if(node->key >= max)
{
max = node->key;
biggest_node = node;
}
node = node->sibling;
}
return biggest_node;
}
bheap_head* fetch_biggest_bheap_node(bheap_head* head)
{
bheap_head* head_after_fetch;
bheap_head* head_changed_biggest_node;
bheap_head* head_before_biggest_node;
bheap_head* head_after_biggest_node;
bheap_head* biggest_node;
bheap_node* curr_node;
bheap_node* pre_node;
bheap_node* tmp_node;
if(NULL == head)
return NULL;
head_after_fetch = NULL;
head_changed_biggest_node = NULL;
head_before_biggest_node = NULL;
head_after_biggest_node = NULL;
biggest_node = get_biggest_bheap_node(head);
curr_node = biggest_node;
pre_node = NULL;
tmp_node = NULL;
if(NULL == curr_node)
return NULL;
if(NULL == curr_node->child)
{
head_after_fetch = curr_node->sibling;
curr_node->sibling = NULL;
return head_after_fetch;
}
curr_node = curr_node->child;
while(NULL != curr_node->sibling)
{
if(NULL == pre_node)
{
pre_node = curr_node;
curr_node= curr_node->sibling;
pre_node->sibling = NULL;
pre_node->parent = NULL;
}
else
{
tmp_node = curr_node;
curr_node = curr_node->sibling;
tmp_node->sibling = pre_node;
pre_node = tmp_node;
pre_node->parent = NULL;
}
}
curr_node->sibling = pre_node;
curr_node->parent = NULL;
head_changed_biggest_node = curr_node;
biggest_node->child = NULL;
tmp_node = head;
while(NULL != tmp_node)
{
if(tmp_node == head && tmp_node == biggest_node)
{
head_before_biggest_node = NULL;
head_after_biggest_node = biggest_node->sibling;
biggest_node->sibling = NULL;
break;
}
if(tmp_node->sibling == biggest_node)
{
head_before_biggest_node = head;
tmp_node->sibling = NULL;
head_after_biggest_node = biggest_node->sibling;
biggest_node->sibling = NULL;
break;
}
tmp_node = tmp_node->sibling;
}
head_after_fetch = union_bheap(head_before_biggest_node, head_changed_biggest_node);
head_after_fetch = union_bheap(head_after_fetch,head_after_biggest_node);
return head_after_fetch;
}
void desrease_bheap_node_key(bheap_node* node, long new_key)
{
long tmp_key;
if(NULL == node)
{
printf("Error: node is NULL!\n");
return ;
}
if(new_key <= node->key)
{
printf("Error: new_key not more than node's key!\n");
return;
}
node->key = new_key;
while((NULL != node->parent) && (node->parent->key < node->key))
{
tmp_key = node->parent->key;
node->parent->key = node->key;
node->key = tmp_key;
node = node->parent;
}
}
bheap_head* deleteb_bheap_node(bheap_head* head, bheap_node* del_node)
{
bheap_node* biggest_bheap_node = get_biggest_bheap_node(head);
long new_key = biggest_bheap_node->key + 1;
desrease_bheap_node_key(del_node, new_key);
head = fetch_biggest_bheap_node(head);
return head;
}
int main()
{
int array[10] = {6,2,-2,8,3,5,4,0,9,1};
int index = 0;
//unchanged array
printf("unchanged array: ");
print(array, 10);
//Creat bheap
bheap_head* head;
bheap_node* node;
bheap_node* biggest_bheap_node;
//long new_key = 10;
while(index < 10)
{
node = creat_bheap_node();
if(0 == index)
head = node;
if(NULL == node)
{
printf("Malloc Error: bheap node == NULL!\n");
break;
}
node->key = array[index];
if(index != 0)
head = insert_bheap_node(head,node);
index ++;
}
print_heap(head);
//search the biggest node
biggest_bheap_node = get_biggest_bheap_node(head);
printf("Biggest Node key: %ld; degree: %d\n", biggest_bheap_node->key,biggest_bheap_node->degree);
/*
head = fetch_biggest_bheap_node(head);
printf("After 1' fetch:\n");
print_heap(head);
biggest_bheap_node = get_biggest_bheap_node(head);
printf("Biggest Node key: %ld; degree: %d\n", biggest_bheap_node->key,biggest_bheap_node->degree);
head = fetch_biggest_bheap_node(head);
printf("After 2' fetch:\n");
print_heap(head);
biggest_bheap_node = get_biggest_bheap_node(head);
printf("Biggest Node key: %ld; degree: %d\n", biggest_bheap_node->key,biggest_bheap_node->degree);
head = fetch_biggest_bheap_node(head);
printf("After 3' fetch:\n");
print_heap(head);
biggest_bheap_node = get_biggest_bheap_node(head);
printf("Biggest Node key: %ld; degree: %d\n", biggest_bheap_node->key,biggest_bheap_node->degree);
head = fetch_biggest_bheap_node(head);
printf("After 4' fetch:\n");
print_heap(head);
biggest_bheap_node = get_biggest_bheap_node(head);
printf("Biggest Node key: %ld; degree: %d\n", biggest_bheap_node->key,biggest_bheap_node->degree);
head = fetch_biggest_bheap_node(head);
printf("After 5' fetch:\n");
print_heap(head);
biggest_bheap_node = get_biggest_bheap_node(head);
printf("Biggest Node key: %ld; degree: %d\n", biggest_bheap_node->key,biggest_bheap_node->degree);
head = fetch_biggest_bheap_node(head);
printf("After 6' fetch:\n");
print_heap(head);
biggest_bheap_node = get_biggest_bheap_node(head);
printf("Biggest Node key: %ld; degree: %d\n", biggest_bheap_node->key,biggest_bheap_node->degree);
head = fetch_biggest_bheap_node(head);
printf("After 7' fetch:\n");
print_heap(head);
biggest_bheap_node = get_biggest_bheap_node(head);
printf("Biggest Node key: %ld; degree: %d\n", biggest_bheap_node->key,biggest_bheap_node->degree);
head = fetch_biggest_bheap_node(head);
printf("After 8' fetch:\n");
print_heap(head);
biggest_bheap_node = get_biggest_bheap_node(head);
printf("Biggest Node key: %ld; degree: %d\n", biggest_bheap_node->key,biggest_bheap_node->degree);
head = fetch_biggest_bheap_node(head);
printf("After 9' fetch:\n");
print_heap(head);
biggest_bheap_node = get_biggest_bheap_node(head);
printf("Biggest Node key: %ld; degree: %d\n", biggest_bheap_node->key,biggest_bheap_node->degree);
head = fetch_biggest_bheap_node(head);
printf("After 10' fetch:\n");
print_heap(head);
*/
node = head->sibling->child->child;
head = deleteb_bheap_node(head, node);
print_heap(head);
biggest_bheap_node = get_biggest_bheap_node(head);
printf("Biggest Node key: %ld; degree: %d\n", biggest_bheap_node->key,biggest_bheap_node->degree);
delete_bheap(head);
return 0;
}
二項堆的講解見《算法導論》中第19章內容,實現如下,與原文中稍有差別,原文要求是最小二項堆,我實現的是最大二項堆,另外部分測試內容、相關注釋沒有寫: