zoukankan      html  css  js  c++  java
  • 二项队列

    二项队列是 堆序 的集合,也叫 森林。其中每一种形式都有约束。

    二项树Bk由一个带有儿子的B0,B1,B2...组成,高度为k的二项树 恰好有2^k个结点。每一种高度只能出现一次...因此,只有1,2,4,8...等结点数目的二项树

    deleteMin操作需要快速的找出跟的所有子树的能力,因此需要一般树的表示方法:

    每个结点的儿子都在一个链表中,而且每个结点都有一个指向它的第一个儿子的指针。

    二项树的每一个结点包括:数据第一个儿子,以及右兄弟

    下面是二项队列类构架及结点定义:

     1 template <typename Comparable>
     2 class BinomialQueue
     3 {
     4 public:
     5     BinomialQueue();
     6     BinomialQueue(const Comparable & item);
     7     BinomialQueue(const BinomialQueue & rhs);
     8     ~BinomialQueue();
     9 
    10     bool isEmpty() const;
    11     const Comparable & findMin() const;
    12 
    13     void insert(const Comparable & x);
    14     void deleteMin();
    15     void deleteMin(Comparable & minItem);
    16 
    17     void makeEmpty();
    18     void merge(BinomialQueue & rhs);
    19 
    20     const BinomialQueue & operator=(const BinomialQueue & rhs);
    21 private:
    22     struct BinomialNode
    23     {
    24         Comparable element;
    25         BinomiaNode *leftChild;
    26         BinomialNode *nextSibling;
    27 
    28         BinomialNode(const Comparable & theElement,BinomialNode *lt,BinomialNode *rt)
    29             :element(theElement),leftChild(lt),rightChild(rt)
    30         {
    31         }
    32     };
    33     
    34     enum{DEFAULT_TREES = 1};
    35 
    36     int currentSize;
    37     vector<BinomialNode *> const;
    38     int capacity() const;
    39     BinomialNode * combineTrees(BinomialNode *t1,BinomialNode *t2);
    40     void makeEmpty(BinomialNode * & t);
    41     BinomialNode * clone(BinomialNode *t) const;
    42 };

    合并同样大小的两棵树二项树的例程:

    1 BinomialNode * combineTrees(BinomialNode *t1,BinomialNode *t2)
    2 {
    3     if(t2->element < t1->element)
    4         return combineTrees(t2,t1);
    5     t1->nextSibling = t1->leftChild;
    6     t1->leftChild = t2;
    7     return t1;
    8 }

    合并两个优先队列的例程:

     1 void merge(BinomialQueue & rhs)
     2 {
     3     if(this==&rhs)
     4         return;
     5     currentSize += rhs.currentSize;
     6     if(currentSize > capacity())
     7     {
     8         int oldNumTrees = theTrees.size();
     9         int newNumTrees = max(theTrees.size(),rhs.theTrees.size())+1;
    10         theTrees.resize(newNumTrees);
    11         for(int i = oldNumTrees; i<newNumTrees; i++)
    12             theTrees[i] = NULL;
    13     }
    14     BinomialNode *carry = NULL;
    15     for(int i=0,j=1; j<=currentSize; i++,j*=2)
    16     {
    17             BinomialNode *t1 = theTrees[i];
    18             BinomialNode *t2 = i < rhs.theTrees.size()? rhs.theTrees[i]:NULL;
    19 
    20             int whichCase = t1 == NULL ? 0 : 1;
    21             whichCase += t2 == NULL? 0 : 2;
    22             whichCase += carry == NULL? 0 : 4;
    23 
    24             switch(whichCase)
    25             {
    26                 case 0:
    27                 case 1:
    28                     break;
    29                 case 2:
    30                     theTrees[i] = t2;
    31                     rhs.theTrees[i] = NULL;
    32                     break;
    33                 case 4:
    34                     theTrees[i] = carry;
    35                     carry = NULL;
    36                     break;
    37                 case 3:
    38                     carry = combineTrees(t1,t2);
    39                     theTrees[i] = rhs.theTrees[i] = NULL;
    40                     break;
    41                 case 5:
    42                     carry = combineTrees(t1,carry);
    43                     theTrees[i] = NULL;
    44                     break;
    45                 case 6:
    46                     carry = combineTrees(t2,carry);
    47                     rhs.theTrees[i] = NULL;
    48                     break;
    49                 case 7:
    50                     theTrees[i] = carry;
    51                     carry = combineTrees(t1,t2);
    52                     rhs.theTrees[i] = NULL;
    53                     break;
    54             }
    55     }
    56     for(int k = 0; k < rhs.theTrees.size(); k++)
    57         rhs.theTrees[k] = NULL;
    58     rhs.currentSize = 0;
    59 }

     deleteMin程序:

     1 void deleteMin(Comparable & minItem)
     2 {
     3     if(isEmpty())
     4         throw UnderflowException();
     5     int minIndex = findMinIndex();
     6     minItem = theTrees[minIndex]->element;
     7 
     8     BinomialNode *oldRoot = theTrees[minIndex];
     9     BinomialNode *deletedTree = oldRoot->leftChild;
    10     delete oldRoot;
    11 
    12     BinomialQueue deletedQueue;
    13     deletedQueue.theTrees.resize(minIndex+1);
    14     deletedQueue.currentSize = (1<<minIndex)-1;
    15     for(int j = minIndex -1 ;j >= 0 ; j--)
    16     {
    17         deletedQueue.theTrees[ j ] = deletedTree;
    18         deletedTree = deletedTree->nextSibling;
    19         deletedQueue.theTrees[ j ]->nextSibling = NULL;
    20     }
    21 
    22     theTrees[minIndex] = NULL;
    23     currentSize -= deletedQueue.currentSize + 1;
    24 
    25     merge(deletedQueue);
    26 } 
    27 int findMinIndex() const
    28 {
    29     int i;
    30     int minIndex;
    31 
    32     for( i = 0; theTrees[i] === NULL;i++)
    33         ;
    34     for(minIndex = i; i < theTrees.size();i++)
    35         if(theTrees[i] != NULL && theTrees[i]->element < theTrees[minIndex]->element)
    36             minIndex = i;
    37 
    38     return minIndex;
    39 }

     

  • 相关阅读:
    ssh scp命令详解
    python模块与包
    python参数Sample Code
    python 多线程简介
    python virtualenv环境安装(ubuntu)
    python pip 代理设置
    mysql资源总结
    mysql索引原理及用法
    Oracle学习笔记:利用user_segments查表的大小
    Oracle学习笔记:dba_tables、all_tables、user_tables区别
  • 原文地址:https://www.cnblogs.com/xing901022/p/2699130.html
Copyright © 2011-2022 走看看