Files
Data-Structure/BinaryTree/tournamentTree/WinnerTree/winnerTree.h
2025-08-11 14:39:57 +08:00

96 lines
2.2 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// 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