数据结构C++(12)赢者树——数组实现(winnerTree)

异常类 myExceptions 同 数据结构C++(1)线性表——数组实现(arrayList) 。

抽象基类  win 定义在 winner.h 中:

 1 #pragma once
 2 
 3 template<class T>
 4 class win
 5 {
 6 public:
 7     virtual ~win() {}
 8     virtual void initialize(T *thePlayer, int theNumberOfPlayers) = 0;    //生成赢者树
 9     virtual int winner() const = 0;            //返回赢者
10     virtual void play(int thePLayerID, int thePLayer) = 0;    //改变thePLayerID的成绩之后重赛
11 };

类 winnerTree 的定义在 winnerTree.h 中:

  1 #pragma once
  2 #include <cmath>
  3 #include "winner.h"
  4 #include "myExceptions.h"
  5 
  6 template<typename T>
  7 class winnerTree : public win<T>
  8 {
  9 public:
 10     winnerTree(T *thePlayer, int theNumberOfPlayers)
 11     {
 12         Tree = NULL;
 13         initialize(thePlayer, theNumberOfPlayers);
 14     }
 15     ~winnerTree() {
 16         std::cout << "~winnerTree Tree = " << Tree << std::endl;
 17         delete []Tree; 
 18         std::cout << "~winnerTree()2" << std::endl;
 19     }
 20     void initialize(T *players, int playerNum);        //初始化,创建赢者树
 21     int winner() const            //最终的胜利者
 22     { return Tree[1]; }
 23     int winner(int i) const        //第 i 场比赛的胜利者
 24     { return (i < numberOfPlayers) ? Tree[i] : 0; }
 25     void play(int thePLayerID, int thePLayer);
 26     void output(std::ostream &out) const;
 27 protected:
 28 //  int lowExt;          
 29     int TreeSize;        
 30     T *Tree;                    //赢者树
 31     int numberOfPlayers;        //参赛人数
 32     T *player;                    //比赛原始数组
 33     void rePlay(int compete, int left, int right);
 34 };
 35 
 36 template<typename T>
 37 void winnerTree<T>::rePlay(int compete, int left, int right)
 38 {
 39     for (int i = compete; i > 0; i /= 2)
 40         Tree[i] = Tree[2 * i] > Tree[2 * i + 1] ? Tree[2 * i] : Tree[2 * i + 1];
 41 }
 42 
 43 template<typename T>
 44 void winnerTree<T>::initialize(T *players, int playerNum)
 45 {
 46     if (playerNum < 2)
 47         throw illegalParameterValue("参赛人数这么点儿,赛个毛啊");
 48     player = players;
 49     numberOfPlayers = playerNum;
 50     delete []Tree;
 51     //playerNum = 5,log_2 = 3,n = 4,TreeSize = 16
 52     int log_2 = log10(playerNum-1) / log10(2) + 1;
 53     int n = pow(2, log_2) - 1;        //最多赛 n 次
 54     TreeSize = pow(2, log_2 + 1);
 55     std::cout << "log_2 = " << log_2 << std::endl;
 56     Tree = new T[TreeSize];    //树最多需要 TreeSize 这么多空间
 57     int TmpNum = TreeSize / 2 - playerNum;
 58     std::cout << "initialize Tree = " << Tree << std::endl;
 59     for (int i = 1, j = 0; i <= TreeSize; i++)
 60     {
 61         std::cout << "Tree[" << i << "] = ";
 62         if (i < pow(2, log_2))                    //先给内部结点填0
 63         {
 64             Tree[i] = 0;
 65             std::cout << Tree[i] << std::endl;
 66         }
 67         else
 68         {
 69             if (i >= TreeSize - TmpNum * 2)    //单人的对手也填0
 70             {
 71                 if (i % 2)
 72                     Tree[i] = 0;
 73                 else
 74                     Tree[i] = players[j++];
 75             }
 76             else
 77                 Tree[i] = players[j++];
 78             std::cout << Tree[i] << std::endl;
 79         }
 80     }
 81     for (int j = n; j >= 1; j--)
 82     {
 83         Tree[j] = Tree[2 * j] > Tree[2 * j + 1] ? Tree[2 * j] : Tree[2 * j + 1];
 84     }
 85 }
 86 
 87 template<typename T>
 88 void winnerTree<T>::play(int thePLayerID, int thePLayer)
 89 {
 90     if (thePLayerID > numberOfPlayers)
 91         throw illegalParameterValue("输入数据太大了!");
 92     player[thePLayerID - 1] = thePLayer;
 93     Tree[thePLayerID + numberOfPlayers] = thePLayer;
 94     int n = (thePLayerID + numberOfPlayers) / 2;
 95     rePlay(n, n * 2, n * 2 + 1);
 96 }
 97 
 98 template<typename T>
 99 void winnerTree<T>::output(std::ostream &out) const
100 {
101     for (int i = 1; i < TreeSize; i++)
102         out << Tree[i] << " ";
103     out << std::endl;
104 }

参考文献:

[1].Sartaj Sahni. 数据结构、算法与应用[M]. 机械工业出版社, 2000.

转载于:https://www.cnblogs.com/peformer/p/8080062.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值