96 lines
2.2 KiB
C++
96 lines
2.2 KiB
C++
//
|
||
// Created by PC on 25-8-11.
|
||
//
|
||
|
||
#ifndef WINNERTREE_H
|
||
#define WINNERTREE_H
|
||
#include <algorithm>
|
||
#include <iostream>
|
||
#include <deque>
|
||
|
||
template <class T>
|
||
class winnerTree {
|
||
private:
|
||
std::deque<T> data;
|
||
int playerNum;
|
||
bool isInit = false;
|
||
public:
|
||
winnerTree() : playerNum(0) {}
|
||
winnerTree(const std::deque<T>& d,int playerNum) : playerNum(playerNum), data(d) {}
|
||
~winnerTree() = default;
|
||
|
||
void init();
|
||
int winner();
|
||
void replay(const T& player, const T& alter);
|
||
void display();
|
||
};
|
||
|
||
template<class T>
|
||
void winnerTree<T>::init() {
|
||
for (int i = 0; i < 2 * playerNum - 2; i+=2) {
|
||
T max = std::max(data.at(i), data.at(i + 1));
|
||
data.push_back(max);
|
||
}
|
||
std::reverse(data.begin(), data.end());
|
||
isInit = true;
|
||
}
|
||
|
||
template<class T>
|
||
int winnerTree<T>::winner() {
|
||
if (!isInit) {
|
||
std::cout << "Uninitialized!" << std::endl;
|
||
return -1;
|
||
}
|
||
return data.front();
|
||
}
|
||
|
||
template<class T>
|
||
void winnerTree<T>::replay(const T &player, const T &alter) {
|
||
int index = -1;
|
||
// 查找叶子节点(可改为用player id更稳妥)
|
||
for (int i = data.size() - playerNum; i < data.size(); i++) {
|
||
if (data[i] == player) {
|
||
data[i] = alter;
|
||
index = i;
|
||
break;
|
||
}
|
||
}
|
||
if (index == -1) {
|
||
std::cout << "No such player!" << std::endl;
|
||
return;
|
||
}
|
||
// 向上调整父节点
|
||
while (index > 0) {
|
||
int parent = (index - 1) / 2;
|
||
int against = (index % 2 == 0) ? index - 1 : index + 1;
|
||
|
||
// 判断against是否越界
|
||
if (against >= data.size()) against = index; // 没对手时自己跟自己比
|
||
|
||
T maxVal = std::max(data.at(index), data.at(against));
|
||
|
||
if (data.at(parent) == maxVal) {
|
||
break; // 父节点胜者不变,提前结束
|
||
}
|
||
data.at(parent) = maxVal;
|
||
index = parent;
|
||
}
|
||
}
|
||
|
||
|
||
template<class T>
|
||
void winnerTree<T>::display() {
|
||
int cnt = 1;
|
||
int jmp = 1;
|
||
for (int i = 0; i < data.size(); ++i) {
|
||
cnt--;
|
||
std::cout << data.at(i) << " ";
|
||
if (cnt == 0) {
|
||
std::cout << std::endl;
|
||
jmp *= 2;
|
||
cnt = jmp;
|
||
}
|
||
}
|
||
}
|
||
#endif //WINNERTREE_H
|