二項堆學習筆記(未完成)

 二項堆:ios

   1.二項堆是由一些二項樹鏈接而成,每一棵二項樹都遵循最小堆性質(即關鍵字的節點大於等於其父親幾點)函數

   2.對任意的度數k,一個二項堆至多有一棵二項樹的根度數爲k (說明一個二項堆最多隻有lgn+1棵二項樹,spa

      將n寫成二進制,每個值爲1的位對應一棵二項樹);code

   二項堆中的各二項樹的根被組織成一個鏈表,稱爲根表,且各根的度數是嚴格遞增的blog

操做:排序

   1.建堆操做:Make-Heap  時間複雜度: O(1)ci

   2.返回最小元素: Minumum   lgnstring

          過程:掃描一遍根表便可找出最小值,每棵二項樹的最小值都在根節點處;io

   3.合併兩個二項堆: Union      lgnclass

          合併過程:先將兩個二項堆的二項樹按度數排序鏈接成一個,而後從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\n", Binomial_Heap_Minimum(H)->data);
104   }
105   cout << "insert successfully!" << endl;
106   return 0;   
107 }
相關文章
相關標籤/搜索