#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define N 10
typedef struct PNode
{
int key;
int degree;
struct PNode *p,*child,*sibling;
}*PLink;
void BINOMIAL_HEAP_MERGE(PLink* pq,PLink* plink)
{//按度进行排序从小到大
PLink h1 = *pq;
PLink h2 = *plink;
PLink header = h1;
PLink prev2 = NULL;
PLink prev1 = NULL;
while (h1&&h2)
{
if (h1->degree >= h2->degree)
{
prev2 = h2;
h2 = h2->sibling;
if (prev1 == NULL)
{
prev2->sibling = h1;
if (h1 == header)
{
header = prev2;
}
}
else
{
prev1->sibling = prev2;
prev2->sibling = h1;
prev1 = prev2;
}
}
else
{
prev1 = h1;
h1 = h1->sibling;
}
}
if (!h1)
{
prev1->sibling = h2;
}
*pq = header;
}
void BINOMIAL_LINK(PLink* y,PLink* z)
{
(*y)->p = *z;
(*y)->sibling = (*z)->child;
(*z)->child = *y;
(*z)->degree = (*z)->degree + 1;
}
//9 6 7 3 7 6 8 0 2 4 ,7 6 2 1 3 1 5 5 7 8
void BINOMIAL_HEAP_Union(PLink* pq,PLink* plink)
{
BINOMIAL_HEAP_MERGE(pq,plink);
PLink x = *pq;
PLink next_x = x->sibling;
PLink prev_x = NULL;
while (next_x)
{
if ((x->degree != next_x->degree)||(next_x->sibling&&(next_x->sibling->degree == x->degree)))
{//第一个节点和第二个节点的度不等,同时第一个节点和第三个节点的度相等
prev_x = x;//前一个节点发生变化
x = next_x;//节点移动
}
else if(x->key <= next_x->key)
{//节点大小比较,x的节点的小于或等于next_x的节点的key
x->sibling = next_x->sibling;//把next_x的节点从主链中断开
BINOMIAL_LINK(&next_x,&x);//将x作为父节点,删除的节点为子节点
}
else
{//x的节点大于next_x的节点的key
if (!prev_x)
{
*pq = next_x;//改变头节点,将头节点变成子节点
}
else
{
prev_x->sibling = next_x;//将prev的下一个节点断开,成为next_x的子节点
}
BINOMIAL_LINK(&x,&next_x);
x = next_x;
}
next_x = x->sibling;
}
}
PLink BINOMIAL_HEAP_Insert(int a[],int n)
{
PLink header = NULL;
for (int i = 0;i < n;++i)
{
PLink temp = malloc(sizeof(*temp));
if (!temp)
{
printf("plink node create failed!!!");
--i;
continue;
}
memset(temp,0, sizeof(*temp));
temp->key = a[i];
temp->degree = 0;
if (i == 0)
{
header = temp;
}
else
{
BINOMIAL_HEAP_Union(&header,&temp);
}
}
return header;
}
#define MINSHORT 0x8000
PLink BINOMIAL_HEAP_MINMUM(PLink* pq)
{
PLink x = *pq;
PLink y = NULL;
int min = MINSHORT;
while (x)
{
if (min > x->key)
{
min = x->key;
y = x;
}
x = x->sibling;
}
return y;
}
PLink BINOMIAL_HEAP_EXTRACT_MIN(PLink header)
{
PLink prevMin = NULL;
PLink PMin = NULL;
PLink p = header;
PLink prev = NULL;
int min = MINSHORT;
while (p)
{
if (min > p->key)
{
prevMin = prev;
PMin = p;
min = p->key;
}
prev = p;
p = p->sibling;
}
PLink header2 = NULL;
PLink next_x = NULL;
if (!prevMin)
{
header2 = PMin;
header = PMin->sibling;
}
else
{
header2 = prevMin->sibling;
prevMin->sibling = prevMin->sibling->sibling;
}
next_x = header2->child;
while (next_x)
{
next_x->p = NULL;
next_x = next_x->sibling;
}
next_x = header2->child;
header2->child = NULL;
BINOMIAL_HEAP_Union(&header,&next_x);
return header;
}
PLink BINOMIAL_HEAP_FIND(PLink header,int k)
{
PLink x = NULL;
PLink h = header;
while (h)
{
if (h->key == k)
{
return h;
}
else
{
if ((x = BINOMIAL_HEAP_FIND(h->child,k)))
{
return h;
}
h = h->sibling;
}
}
return NULL;
}
PLink BINOMIAL_HEAP_DECREASE_MIN(PLink header,PLink k,int key)
{
k = BINOMIAL_HEAP_FIND(header,k->key);
if (!k)
{
return NULL;
}
if (key > k->key)
{
printf(">");
return NULL;
}
k->key = key;
PLink y = k;
PLink z = y->p;
while (z&&(y->key < z->key))
{
int temp = y->key;
y->key = z->key;
z->key = temp;
y = z;
z = y->p;
}
return header;
}