#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<climits>
using namespace std;
typedef struct BinHeapNode BinNode;
typedef struct BinHeapNode * BinHeap;
typedef struct BinHeapNode * Position;
struct BinHeapNode
{
int key;
int degree;
Position parent;
Position leftChild;
Position sibling;
};
BinHeap MakeBinHeapWithArray(int keys[], int n);
BinHeap BinHeapUnion(BinHeap &H1, BinHeap &H2);
BinHeap BinHeapMerge(BinHeap &H1, BinHeap &H2);
void BinLink(BinHeap &H1, BinHeap &H2);
BinHeap BinHeapMin(BinHeap heap);
void BinHeapDecreaseKey(BinHeap heap, BinHeap x, int key);
BinHeap BinHeapDelete(BinHeap &heap, int key);
BinHeap BinHeapFind(BinHeap &heap, int key);
void PrintBinHeap(BinHeap heap);
BinHeap BinHeapInsert(BinHeap heap,int key);
void DestroyBinHeap(BinHeap &heap);
BinHeap MakeBinHeapWithArray(int keys[], int n)
{
BinHeap heap = NULL, newHeap = NULL;
for (int i = 0; i < n; i++)
{
newHeap = (BinHeap) malloc(sizeof(BinNode));
if (newHeap == NULL)
{
puts("Out of the Space");
exit(1);
}
memset(newHeap, 0, sizeof(BinNode));
newHeap->key = keys[i];
if (NULL == heap)
{
heap = newHeap;
}
else
{
heap = BinHeapUnion(heap, newHeap);
newHeap = NULL;
}
}
return heap;
}
BinHeap BinHeapUnion(BinHeap &H1, BinHeap &H2)
{
Position heap = NULL, pre_x = NULL, x = NULL, next_x = NULL;
heap = BinHeapMerge(H1, H2);
if (heap == NULL)
{
return heap;
}
x = heap;
next_x = x->sibling;
while (next_x != NULL)
{
if ((x->degree != next_x->degree) ||
((next_x->sibling != NULL) && (next_x->degree == next_x->sibling->degree)))
{
pre_x = x;
x = next_x;
}
else if (x->key <= next_x->key)
{
x->sibling = next_x->sibling;
BinLink(next_x, x);
}
else
{
if (pre_x == NULL)
{
heap = next_x;
}
else
{
pre_x->sibling = next_x;
}
BinLink(x, next_x);
x = next_x;
}
next_x = x->sibling;
}
return heap;
}
BinHeap BinHeapMerge(BinHeap &H1, BinHeap &H2)
{
BinHeap heap = NULL, firstHeap = NULL, secondHeap = NULL,
pre_H3 = NULL, H3 = NULL;
if (H1 != NULL && H2 != NULL)
{
firstHeap = H1;
secondHeap = H2;
while (firstHeap != NULL && secondHeap != NULL)
{
if (firstHeap->degree <= secondHeap->degree)
{
H3 = firstHeap;
firstHeap = firstHeap->sibling;
}
else
{
H3 = secondHeap;
secondHeap = secondHeap->sibling;
}
if (pre_H3 == NULL)
{
pre_H3 = H3;
heap = H3;
}
else
{
pre_H3->sibling = H3;
pre_H3 = H3;
}
if (firstHeap != NULL)
{
H3->sibling = firstHeap;
}
else
{
H3->sibling = secondHeap;
}
}
}
else if (H1 != NULL)
{
heap = H1;
}
else
{
heap = H2;
}
H1 = H2 = NULL;
return heap;
}
void BinLink(BinHeap &H1, BinHeap &H2)
{
H1->parent = H2;
H1->sibling = H2->leftChild;
H2->leftChild = H1;
H2->degree++;
}
BinHeap BinHeapMin(BinHeap heap)
{
Position y = NULL, x = heap;
int min = INT_MAX;
while (x != NULL)
{
if (x->key < min)
{
min = x->key;
y = x;
}
x = x->sibling;
}
return y;
}
BinHeap BinHeapExtractMin(BinHeap &heap)
{
BinHeap pre_y = NULL, y = NULL, x = heap;
int min = INT_MAX;
while (x != NULL)
{
if (x->key < min)
{
min = x->key;
pre_y = y;
y = x;
}
x = x->sibling;
}
if (y == NULL)
{
return NULL;
}
if (pre_y == NULL)
{
heap = heap->sibling;
}
else
{
pre_y->sibling = y->sibling;
}
BinHeap H2 = NULL, p = NULL;
x = y->leftChild;
while (x != NULL)
{
p = x;
x = x->sibling;
p->sibling = H2;
H2 = p;
p->parent = NULL;
}
heap = BinHeapUnion(heap, H2);
return y;
}
BinHeap BinHeapInsert(BinHeap heap,int key){
BinHeap newHeap=NULL;
newHeap=(BinHeap)malloc(sizeof(BinNode));
if(newHeap == NULL){
puts("Out of the Space!");
exit(1);
}
memset(newHeap,0,sizeof(BinNode));
newHeap->key=key;
heap = BinHeapUnion(heap,newHeap);
newHeap = NULL;
return heap;
}
void BinHeapDecreaseKey(BinHeap heap, BinHeap x, int key)
{
if(key > x->key)
{
puts("new key is greaer than current key");
exit(1);
}
x->key = key;
BinHeap z = NULL, y = NULL;
y = x;
z = x->parent;
while(z != NULL && z->key > y->key)
{
swap(z->key, y->key);
y = z;
z = y->parent;
}
}
BinHeap BinHeapDelete(BinHeap &heap, int key)
{
BinHeap x = NULL;
x = BinHeapFind(heap, key);
if (x != NULL)
{
BinHeapDecreaseKey(heap, x, INT_MIN);
return BinHeapExtractMin(heap);
}
return x;
}
BinHeap BinHeapFind(BinHeap &heap, int key)
{
Position p = NULL, x = NULL;
p = heap;
while (p != NULL)
{
if (p->key == key)
{
return p;
}
else
{
if((x =BinHeapFind(p->leftChild, key)) != NULL)
{
return x;
}
p = p->sibling;
}
}
return NULL;
}
void PrintBinHeap(BinHeap heap)
{
if (NULL == heap)
{
return ;
}
Position p = heap;
while (p != NULL)
{
printf(" (");
printf("%d", p->key);
if(NULL != p->leftChild)
{
PrintBinHeap(p->leftChild);
}
printf(") ");
p = p->sibling;
}
}
int kp1[7] = {12,
7, 25,
15, 28, 33, 41
};
int kp2[19] = {18,
3, 37,
6, 8, 29, 10, 44, 30, 23, 2, 48, 31, 17, 45, 32, 24, 50, 55
};
int kp4[22] = {37, 41,
10, 28, 13, 77,
1, 6, 16, 12, 25, 8, 14, 29, 26, 23, 18, 11, 17, 38, 42, 27
};
int kp5[5]={1,
3,5,7,9,};
int main()
{
printf("\nMutually Independent Parentheses Indicate that They are Siblings\n\nIn Each Parenthese, the first value is the root ,second is its leftchild, third one is its rightchild\n\n");
BinHeap H1 = NULL;
H1 = MakeBinHeapWithArray(kp1, sizeof(kp1)/sizeof(int));
puts("第一个二叉堆H1:");
PrintBinHeap(H1);
BinHeap H5 = NULL;
H5 = MakeBinHeapWithArray(kp5, sizeof(kp5)/sizeof(int));
puts("\n\n第二个二叉堆H5:");
PrintBinHeap(H5);
BinHeap H3 = NULL;
H3 = BinHeapUnion(H1, H5);
puts("\n\n合并H1,H5后,得到H3:");
PrintBinHeap(H3);
BinHeap H6=NULL;
H6=BinHeapInsert(H3,8);
puts("\n\n插入数值8后,得到H6:");
PrintBinHeap(H6);
BinHeap H4 = NULL;
H4 = MakeBinHeapWithArray(kp4, sizeof(kp4)/sizeof(int));
puts("\n\n用于测试提取和删除的二叉堆H4:");
PrintBinHeap(H4);
BinHeap extractNode = BinHeapExtractMin(H4);
if (extractNode != NULL)
{
printf("\n\n抽取最小的值%d后:\n", extractNode->key);
PrintBinHeap(H4);
}
extractNode = BinHeapExtractMin(H4);
if (extractNode != NULL)
{
printf("\n\n抽取最小的值%d后:\n", extractNode->key);
PrintBinHeap(H4);
}
extractNode = BinHeapExtractMin(H4);
if (extractNode != NULL)
{
printf("\n\n抽取最小的值%d后:\n", extractNode->key);
PrintBinHeap(H4);
}
BinHeapDelete(H4, 12);
puts("\n\n删除12后:");
PrintBinHeap(H4);
return 0;
}