⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 completewinnertree.h

📁 datastucutre and algorithms, application, in C
💻 H
字号:
// winner tree as a complete binary tree mapped into an array
// derives from the ADT winnerTree

#ifndef completeWinnerTree_
#define completeWinnerTree_

#include <iostream>
#include "winnerTree.h"
#include "myExceptions.h"

template<class T>
class completeWinnerTree : public winnerTree<T>
{
   public:
      completeWinnerTree(T *thePlayer, int theNumberOfPlayers)
         {
            tree = NULL;
            initialize(thePlayer, theNumberOfPlayers);
         }
      ~completeWinnerTree() {delete [] tree;}
      void initialize(T*, int);
      int winner() const
         {return tree[1];}
      int winner(int i) const
         {return (i < numberOfPlayers) ? tree[i] : 0;}
         // return winner of match at node i
      void rePlay(int);
      void output() const;
   private:
      int lowExt;           // lowest-level external nodes
      int offset;           // 2^log(n-1) - 1
      int *tree;            // array for winner tree
      int numberOfPlayers;
      T *player;            // array of players
      void play(int, int, int);
};

template<class T>
void completeWinnerTree<T>::initialize(T *thePlayer,
                                       int theNumberOfPlayers)
{// Create winner tree for thePlayer[1:numberOfPlayers].
   int n = theNumberOfPlayers;
   if (n < 2)
      throw illegalParameterValue("must have at least 2 players");

   player = thePlayer;
   numberOfPlayers = n;
   delete [] tree;
   tree = new int [n];

   // compute  s = 2^log (n-1)
   int i, s;
   for (s = 1; 2 * s <= n - 1; s += s);

   lowExt = 2 * (n - s);
   offset = 2 * s - 1;

   // play matches for lowest-level external nodes
   for (i = 2; i <= lowExt; i += 2)
      play((offset + i) / 2, i - 1, i);

   // handle remaining external nodes
   if (n % 2 == 1)
   {// special case for odd n, play internal and exteral node
      play(n/2, tree[n - 1], lowExt + 1);
      i = lowExt + 3;
   }
   else i = lowExt + 2;

   // i is left-most remaining external node
   for (; i <= n; i += 2)
      play((i - lowExt + n - 1) / 2, i - 1, i);
}

template<class T>
void completeWinnerTree<T>::play(int p, int leftChild, int rightChild)
{// play matches beginning at tree[p]
 // leftChild is left child of p
 // rightChild is right child of p

   tree[p] = (player[leftChild] <= player[rightChild]) ?
                   leftChild : rightChild;

   // more matches possible if at right child
   while (p % 2 == 1 && p > 1)
   {// at a right child
      tree[p / 2] = (player[tree[p - 1]] <= player[tree[p]]) ?
                       tree[p - 1] : tree[p];
      p /= 2;  // go to parent
   }
}


template<class T>
void completeWinnerTree<T>::rePlay(int thePlayer)
{// Replay matches for player thePlayer.
   int n = numberOfPlayers;
   if (thePlayer <= 0 || thePlayer > n)
      throw illegalParameterValue("Player index is illegal");

   int matchNode,       // node where next match is to be played
       leftChild,       // left child of matchNode
       rightChild;      // right child of matchNode

   // find first match node and its children
   if (thePlayer <= lowExt)
   {// begin at lowest level
      matchNode = (offset + thePlayer) / 2;
      leftChild = 2 * matchNode - offset;
      rightChild = leftChild + 1;
   }
   else
   {
      matchNode = (thePlayer - lowExt + n - 1) / 2;
      if (2 * matchNode == n - 1)
      {
         leftChild = tree[2 * matchNode];
         rightChild = thePlayer;
      }
      else
      {
         leftChild = 2 * matchNode - n + 1 + lowExt;
         rightChild = leftChild + 1;
      }
   }

   tree[matchNode] = (player[leftChild] <= player[rightChild])
                            ? leftChild : rightChild;

   // special case for second match
   if (matchNode == n - 1 && n % 2 == 1)
   {
      matchNode /= 2;   // move to parent
      tree[matchNode] = (player[tree[n - 1]] <=
                         player[lowExt + 1]) ?
                        tree[n - 1] : lowExt + 1;
   }

   // play remaining matches
   matchNode /= 2;  // move to parent
   for (; matchNode >= 1; matchNode /= 2)
      tree[matchNode] = (player[tree[2 * matchNode]] <=
                         player[tree[2 * matchNode + 1]]) ?
                        tree[2 * matchNode] : tree[2 * matchNode + 1];
}

template<class T>
void completeWinnerTree<T>::output() const
{
   cout << "number of players  = " << numberOfPlayers
        << " lowExt = " << lowExt
        << " offset = " << offset << endl;
   cout << "complete winner tree pointers are" << endl;
   for (int i = 1; i < numberOfPlayers; i++)
      cout << tree[i] << ' ';
   cout << endl;
}

#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -