// // Created by PC on 25-8-11. // #ifndef WINNERTREE_H #define WINNERTREE_H #include #include #include template class winnerTree { private: std::deque data; int playerNum; bool isInit = false; public: winnerTree() : playerNum(0) {} winnerTree(const std::deque& d,int playerNum) : playerNum(playerNum), data(d) {} ~winnerTree() = default; void init(); int winner(); void replay(const T& player, const T& alter); void display(); }; template void winnerTree::init() { for (int i = 0; i < 2 * playerNum - 2; i+=2) { T max = std::min(data.at(i), data.at(i + 1)); data.push_back(max); } std::reverse(data.begin(), data.end()); isInit = true; } template int winnerTree::winner() { if (!isInit) { std::cout << "Uninitialized!" << std::endl; return -1; } return data.front(); } template void winnerTree::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::min(data.at(index), data.at(against)); if (data.at(parent) == maxVal) { break; // 父节点胜者不变,提前结束 } data.at(parent) = maxVal; index = parent; } } template void winnerTree::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