二項隊列

二項隊列是 堆序 的集合,也叫 森林。其中每一種形式都有約束。this

二項樹Bk由一個帶有兒子的B0,B1,B2...組成,高度爲k的二項樹 剛好有2^k個結點。每一種高度只能出現一次...所以,只有1,2,4,8...等結點數目的二項樹spa

deleteMin操做須要快速的找出跟的全部子樹的能力,所以須要通常樹的表示方法:指針

每一個結點的兒子都在一個鏈表中,並且每一個結點都有一個指向它的第一個兒子的指針。code

二項樹的每個結點包括:數據第一個兒子,以及右兄弟blog

下面是二項隊列類構架及結點定義:隊列

 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 };

合併一樣大小的兩棵樹二項樹的例程:ci

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 }

合併兩個優先隊列的例程:element

 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程序:it

 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 }
相關文章
相關標籤/搜索