排序功能完备的二项堆

插入的时候采用了不同的数据插入顺序,但排序的结果是一样的。

level=0  key=33
level=1  key=55
level=0  key=12
level=1  key=21
level=2  key=77
level=3  key=221
level=2  key=345
level=1  key=44
level=2  key=67
level=1  key=34
12 
21 
33 
34 
44 
55 
67 
77 
221 
345 
level=0  key=12
level=1  key=34
level=0  key=21
level=1  key=33
level=2  key=77
level=3  key=221
level=2  key=55
level=1  key=44
level=2  key=67
level=1  key=345
12 
21 
33 
34 
44 
55 
67 
77 
221 
345 

¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥

#include  <stdio.h>
#include  <stdlib.h>

#define  NIL  9999
typedef  struct  _binheap
{
  int  key;
  int degree;
  struct  _binheap  *parent;
  struct  _binheap  *sib;
  struct  _binheap  *child;
}binheap;

binheap  *  newconstruct ( int key)
{
  binheap *obj=(binheap*)calloc (1 ,sizeof (binheap));
  obj->key=key;
  return  obj;
}

binheap  *  nilconstruct ()
{
  static binheap *nilobj=NULL;
  if(!nilobj)
    {
      nilobj=(binheap*)calloc (1 ,sizeof (binheap));
      nilobj->key=NIL;
    }
  else
    {
    }
  return  nilobj;
}

binheap * binheap_merge ( binheap *left , binheap *right )
{
  //funck  sohu
 
  if( !left )
    {
      return  right;
    }
  if( !right)
    {
      return  left;
    }
  if( left->degree < right->degree)
    {
      left->sib= binheap_merge ( left->sib , right);
      return  left;
    }
  else
    { 
      right->sib= binheap_merge ( left , right->sib);
      return  right;
    }
}

void  re_link (binheap *left , binheap *right )

  right->degree+=1;
  left->sib=right->child;
  right->child=left;
}

binheap * binheap_union ( binheap *left , binheap *right )
{
  binheap  *pre_x,*x,*next_x,*next_next_x;
  binheap  *wrap_head=nilconstruct ();
  int label=0;
  wrap_head->sib=binheap_merge(left,right);
  pre_x=wrap_head;
  while(1)
    {
      x=pre_x->sib;
      if( !x)
 {
   break;
 }
      if(! x->sib)
 {
   pre_x=x;  //for  formallism
 }
      else
 {
   next_x=x->sib;
   if( x->degree!=next_x->degree )
     {
       pre_x=x;
     }
   else
     {   
       if ( ! next_x->sib)
  {
    if( x->key > next_x->key)
      {
        pre_x->sib=next_x;    
        re_link ( x ,next_x);
     
      }
    else
      {  
        x->sib=next_x->sib;
        re_link( next_x , x);
     
      }
  }
       else
  {
    next_next_x=next_x->sib;   
    if(  next_x->degree !=next_next_x->degree )
      {
        if( x->key > next_x->key)
   {
     pre_x->sib=next_x;    
     re_link ( x ,next_x);
      
   }
        else
   {  
     x->sib=next_x->sib;
     re_link( next_x , x);
      
   }
      }
    else
      { 
        pre_x=x;
      }  
  }
     }
 } 
    }
  return  wrap_head->sib;
}

void insert (binheap  *newobj ,binheap * * head)
{
  if(!*head)
    {
      *head=newobj;
    }
  else
    {
      *head=binheap_union( newobj , *head);
    }
}
void  print(binheap *head,int level)
{
  if(!head)
    {
    }
  else
    {
      printf("level=%d  key=%d \n",level,head->key); 
      print (head->child,level+1);

      print(head->sib,level);
    }
}

binheap  *reverse ( binheap  *head)
{
  binheap *left=NULL;
  binheap  *right=NULL;
  if(!head)
    {
      return  NULL;
    }
  while( head->sib )
    {
      right=head->sib;

      head->sib=left;
      left=head;
      head=right;
    }
  head->sib=left;
  return  head;
}

binheap  * pop (binheap  **_head )
{
  binheap  *head=*_head;
  binheap  *result=NULL;
  binheap  *min=NULL;
  int  key=9999999;
  binheap  *wrap_head=nilconstruct ();
  while(head)
    {
      if (head->key<key)
 {
   key=head->key;
   min=head;
 }
      head=head->sib;
    }

  wrap_head->sib=*_head;
  head=wrap_head;
  while(head)
    {
      if(head->sib==min)
 {
   head->sib=min->sib;
   break;
 }
      head=head->sib;
    }
  *_head=wrap_head->sib;

  result=min;

  head= reverse  ( min->child);
  *_head=binheap_union (head ,*_head);
 
  result->sib=NULL;
  result->child=NULL;
  return  result;
}

int main()
{

  int i;
  binheap  *head=NULL;
  binheap  *newobj=NULL;
  binheap  *result=NULL;
  int  key[]={12,34,67,44,21,345,221,77,55,33};
  result=(binheap *)calloc  (  sizeof (key)/sizeof (int )  ,sizeof (binheap));

  for(i=0;i<sizeof (key) /sizeof (int) ;i++)
    {
      newobj=newconstruct (key[i]);
      insert ( newobj , &head); 
    }
  print(head,0);

  //pop the result 

  while(head)
    {
      newobj=pop ( &head);
      printf("%d  \n", newobj->key); 
    }


  //insert  in  reverse  order
  for(i=sizeof (key) /sizeof (int)-1;i>=0 ;i--)
    {
      newobj=newconstruct (key[i]);
      insert ( newobj , &head); 
    }
  print(head,0);

  //pop the result 

  while(head)
    {
      newobj=pop ( &head);
      printf("%d  \n", newobj->key); 
    }
 
}

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值