二项堆实现

#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;

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值