WinnerTree

This commit is contained in:
e2hang
2025-08-11 14:39:57 +08:00
parent 89639d8705
commit ba9ceaab14
5 changed files with 148 additions and 0 deletions

View File

@@ -0,0 +1,6 @@
## 优先级队列
|应用|说明|
|---|---|
|堆排序|maxHeap|
|机器调度|类似最小堆排序|
霍夫曼编码 Huffman|压缩算法,重点|

View File

@@ -0,0 +1,6 @@
cmake_minimum_required(VERSION 3.31)
project(winnerTree)
set(CMAKE_CXX_STANDARD 20)
add_executable(winnerTree main.cpp)

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

View File

@@ -0,0 +1,41 @@
#include "winnerTree.h"
using namespace std;
int main() {
//输入的时候d反转一下好像没必要哈
deque<int> q;
q.push_back(1);
q.push_back(2);
q.push_back(3);
q.push_back(4);
q.push_back(5);
q.push_back(6);
q.push_back(7);
q.push_back(8);
q.push_back(9);
q.push_back(10);
winnerTree<int> t(q, 10);
t.init();
cout << t.winner() << endl;
t.display();
cout << endl;
t.replay(6, 11);
cout << t.winner() << endl;
t.display();
return 0;
}
/*
非常正确的竞赛树
10
10
10 8
4 10 8 6
4 2 10 9 8 7 6 5
4 3 2 1
11
11
10 11
4 10 8 11
4 2 10 9 8 7 11 5
4 3 2 1
*/

View File

@@ -0,0 +1,95 @@
//
// 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