test

来源:互联网 发布:centos设置不锁屏 编辑:程序博客网 时间:2024/06/05 02:42


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

typedef struct bhnode {
 int key;
 struct bhnode *parent;
 struct bhnode *sibling;
 struct bhnode *child;
 int degree;
} BHNode;

typedef BHNode /**BTREE, */*BHEAP;

#ifndef INFINITE
#define INFINITE 0xffff
#endif

BHNode *BinomialHeapMinimum(BHEAP bh)
{
 BHNode *y = NULL; // 记录最小关键字的结点
 BHNode *x = bh;
 int min = INFINITE;

 while (x != NULL) {
  if (x->key < min) {
   min = x->key;
   y = x;
  }
  x = x->sibling;
 }

 return y;
}

// 连接两棵二项树,其中z为新的根
BHNode *BinomialLink(BHNode *y, BHNode *z)
{
 y->parent = z;
 y->sibling = z->child;
 z->child = y;
 z->degree++;

 return z;
}

// 合并二项堆h1与h2
BHNode *BinomialHeapMerge(BHNode *h1, BHNode *h2)
{
 BHNode *head = NULL; // 注意
 BHNode **pos = &head;

 while (h1 != NULL && h2 != NULL) {
  if (h1->degree < h2->degree) {
   *pos = h1;
   h1 = h1->sibling;
  } else {
   *pos = h2;
   h2 = h2->sibling;  
  }
  pos = &(*pos)->sibling;
 }
 if (h1)
  (*pos) = h1;
 else
  (*pos) = h2;

 return head;
}

// 合并连个二项堆,着重理解
BHNode *BinomialHeapUnion(BHNode *h1, BHNode *h2)
{
 BHNode *head = NULL;
 BHNode *prev, *x, *next;

 head = BinomialHeapMerge(h1, h2);
 if (head == NULL)
  return head;

 prev = NULL;
 x = head;
 next = x->sibling;
 while (next != NULL) {
  if ((x->degree != next->degree) ||  // cases 1 and 2
   (next->sibling != NULL && next->sibling->degree == x->degree)) {
      // nothing to do, advance
   prev = x;
   x = next;
  } else if (x->key <= next->key) { // case 3
   // x becomes the root of next
   x->sibling = next->sibling;
   x = BinomialLink(next, x);
  } else {                           // case 4
   // next becomes the root of x
   if (prev == NULL)
    head = next;
   else
    prev->sibling = next;
   next = BinomialLink(x, next);
   x = next; 
  }
  next = x->sibling;
 }

 return head;
}

BHNode *BinomialHeapInsert(BHEAP h, BHNode *x)
{
 BHNode *head = x;

 head = BinomialHeapUnion(h, head);

 return head;
}

// 链表的反转
BHNode *BinomialReverse(BHNode *x)
{
 BHNode *p, *q, *tmp;

 p = x;
 if (!p || !p->sibling)
  return p;

 q = p->sibling;
 while (q) {
  tmp = q->sibling;
  q->sibling = p;
  p = q;
  q = tmp;
 }

 return p;
}

BHNode *BinomialHeapExtractMin(BHEAP h)
{
 BHNode *min = BinomialHeapMinimum(h);

 // remove min from the root list of h
 BHNode *prev = h;
 if (prev == min) {
  if (prev->sibling != NULL)
   h = prev->sibling;
  else
   h = NULL;
 } else { // 找到最小关键字结点的前驱
  while (prev->sibling != min)
   prev = prev->sibling;
  prev->sibling = min->sibling;
 }
 
 BHNode *h2 = BinomialReverse(min->child);
 
 h = BinomialHeapUnion(h, h2);

 return h;
}

int main()
{
 int arr[] = {342, 5, 23, 43, 53, 123, 50, 890};
 int len = sizeof(arr) / sizeof(arr[0]);
 BHEAP bh = NULL;
 
 for (int i = 0; i < len; i++) {
  BHNode *x = (BHNode *)malloc(sizeof(BHNode));
  if (!x) {
   printf("x malloc error\n");
   return -1;
  }
  x->key = arr[i];
  x->parent = NULL;
  x->sibling = NULL;
  x->child = NULL;
  x->degree = 0;
  bh = BinomialHeapUnion(bh, x);
 }

 BHNode *min;
 min = BinomialHeapMinimum(bh);
 printf("min = %d\n", min->key);

 bh = BinomialHeapExtractMin(bh);

 min = BinomialHeapMinimum(bh);
 printf("min = %d\n", min->key);

 system("pause");
 return 0;
}



0 0
原创粉丝点击