二项队列

来源:互联网 发布:overture中文版mac 编辑:程序博客网 时间:2024/05/29 02:36

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

二项树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 BinomialNode23     {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() const28 {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 }
复制代码

 

 

原创粉丝点击