zoukankan      html  css  js  c++  java
  • 二项堆学习笔记(未完成)

     二项堆:

       1.二项堆是由一些二项树连接而成,每一棵二项树都遵循最小堆性质(即关键字的节点大于等于其父亲几点)

       2.对任意的度数k,一个二项堆至多有一棵二项树的根度数为k (说明一个二项堆最多只有lgn+1棵二项树,

          将n写成二进制,每一个值为1的位对应一棵二项树);

       二项堆中的各二项树的根被组织成一个链表,称为根表,且各根的度数是严格递增的

    操作:

       1.建堆操作:Make-Heap  时间复杂度: O(1)

       2.返回最小元素: Minumum   lgn

              过程:扫描一遍根表即可找出最小值,每棵二项树的最小值都在根节点处;

       3.合并两个二项堆: Union      lgn

              合并过程:先将两个二项堆的二项树按度数排序连接成一个,然后从Head开始扫描根表,遇到相邻度数

                            相等的二项树就将其合并为一棵二项树,分为4种情况。

              合并需要用到两个辅助函数:

              1.Binomial_Link() : 合并两棵二项树  O(1)

              2.Binomal-Heap-Merge(): 将两个二项堆的各二项树按度数从小到大排序连接起来 lgn

       4.插入新元素  Insert            lgn

            过程: 插入过程其实是先为新元素单独建一个二项堆,然后调用Union操作将该二项堆与原来的二项堆合

                     并起来。

      1 #include <iostream>
      2 #include <cstring>
      3 using namespace std;
      4 const int INF = 1000000;
      5 struct Node {
      6   int data, degree;
      7   Node *p, *child, *sibling;
      8   Node(int data_, int degree_, Node* p_, Node* child_, Node* sibling_) {
      9       data = data_;  degree = degree_;  p = p_;
     10       child = child_;  sibling = sibling_;
     11   }
     12 };
     13 //新建二叉堆 
     14 Node* Make_Binomial_Heap() {
     15   Node* Binomial_Heap = NULL;
     16   return Binomial_Heap;
     17 }
     18 //返回最小元素 
     19 Node* Binomial_Heap_Minimum(Node* &H) {
     20   Node *x = H, *y = NULL;
     21   int min = INF;
     22   while (x != NULL) {
     23     if (x->data < min) {
     24       min = x->data;
     25       y = x;
     26     }
     27     x = x->sibling;
     28   }
     29   return y;
     30 }
     31 //基本操作:连接两棵二项树
     32 Node* Binomial_Link(Node* &y, Node* &z) {
     33   y->p = z;
     34   y->sibling = z->child;
     35   z->child = y;
     36   z->degree += 1;
     37 }
     38 //将H1和H2的根表合并成一个按度数单调递增次序排列的链表
     39 Node* Binomial_Heap_Merge(Node* &H1, Node* &H2) {
     40   Node* H = NULL, *ptr = NULL;
     41   Node* ptr1 = H1, *ptr2 = H2;
     42   while (ptr1 || ptr2) {
     43       if (ptr1 == NULL || (ptr2 && ptr1->data > ptr2->data)) {
     44         if (H == NULL) {
     45           ptr = ptr2; H = ptr; ptr2 = ptr2->sibling;
     46         } else {
     47           ptr->sibling = ptr2; ptr = ptr->sibling; ptr2 = ptr2->sibling;
     48         }
     49       } else if (ptr2 == NULL || (ptr1 && ptr1->data <= ptr2->data)) {
     50         if (H == NULL) {
     51             ptr = ptr1; H = ptr; ptr1 = ptr1->sibling;
     52         } else {
     53             ptr->sibling = ptr1; ptr = ptr->sibling; ptr1 = ptr1->sibling;
     54         }
     55       }
     56   }
     57   return H;
     58 }
     59 //合并两个二项堆
     60 Node* Binomial_Heap_Union(Node* &H1, Node* &H2) {
     61   Node* H = Make_Binomial_Heap();
     62   H = Binomial_Heap_Merge(H1, H2);
     63   H1 = H2 = NULL;
     64   if (H == NULL) return H;
     65   Node* x, *pre_x, *next_x;
     66   x = H; pre_x = NULL; next_x = x->sibling;
     67   while (next_x != NULL) {
     68       if ((x->degree != next_x->degree) || (next_x->sibling && 
     69           (x->degree == (next_x->sibling)->degree))) {  //case1  and case 2
     70         pre_x = x;  x = next_x; 
     71       } else if (x->data <= next_x->data){   //case3
     72         x->sibling = next_x->sibling;
     73         Binomial_Link(next_x, x);
     74       } else {                               //case4
     75         if (pre_x == NULL) {
     76           H = next_x;
     77         } else {
     78             pre_x->sibling = next_x;
     79         }
     80         Binomial_Link(x, next_x);
     81         x = next_x;
     82       }
     83     next_x = x->sibling;
     84   }
     85   return H;
     86 }
     87 //插入新元素 
     88 Node* Binomial_Heap_Insert(Node* &H, int x) {
     89   Node* H1 = Make_Binomial_Heap();
     90   H1 = new Node(x, 0, NULL, NULL, NULL);
     91   H = Binomial_Heap_Union(H, H1);
     92   return H;
     93 }
     94 
     95 
     96 int main()
     97 {
     98   Node* H = Make_Binomial_Heap();
     99   int a, n; 
    100   for (int i = 0; i < 10; i++) {
    101       cin >> a;
    102       Binomial_Heap_Insert(H, a);
    103       printf("%d
    ", Binomial_Heap_Minimum(H)->data);
    104   }
    105   cout << "insert successfully!" << endl;
    106   return 0;   
    107 }
  • 相关阅读:
    io
    文件
    诚实
    没有犯错并不代表自己就是做得好
    脑力锻炼的随缘
    电路运算
    “容错率”
    GPU简介
    名与责任
    失眠和精神的思考
  • 原文地址:https://www.cnblogs.com/Patrickcxt/p/3499754.html
Copyright © 2011-2022 走看看