#ifndef WINNERTREE_H_#include "main.h"template<class T>class winnerTree{public: virtual ~winnerTree() {} //用数组thePlayer[1:numberOfPlayers]生成赢者树 virtual void initialize(T *thePlayer, int theNumberOfPlayers) = 0; //返回最终赢者的索引 virtual int winner()const = 0; //在参赛者thePLayer的分数变化后重赛 virtual void rePlay(int thePlayer) = 0;};#endif
#ifndef COMPLETEWINNERTREE_H_#include "main.h"#include "myExceptions.h"#include "winnerTree.h"template<class T>class completeWinnerTree :public winnerTree<T>{public: completeWinnerTree(T *thePlayer, int theNumerOfPlayers) { //构造函数,将赢者树初始化为空,然后生成赢者树 this->tree = nullptr; initialize(thePlayer, theNumerOfPlayers); } ~completeWinnerTree() { //析构函数 if (tree) { delete[] tree; } tree = nullptr; } //用数组thePlayer[1:numberOfPlayers]生成赢者树 void initialize(T *thePlayer, int theNumberOfPlayers)override; //返回最终赢者的索引 int winner()const override { return this->tree[1]; } //返回竞赛树某个节点的赢者 int winner(int i) const{ return (i < this->numberOfPlayers) ? this->tree[i] : 0; } //在参赛者thePLayer的分数变化后重赛 void rePlay(int thePlayer)override; //输出赢者树中的一些信息 void output()const;private: /* 对tree[p]节点进行比赛,leftChild为左子节点,rightChild为右子节点 如果还有父节点,继续向上比赛 */ void play(int p, int leftChild, int rightChild);private: int lowExt; //最底层外部节点个数 int offset; //offset=2*s-1(s为最底层最左端的内部节点) int *tree; //赢者树 int numberOfPlayers;//竞赛选手的数量 T *player; //保存竞赛选手};//用数组thePlayer[1:numberOfPlayers]生成赢者树template<class T>void completeWinnerTree<T>::initialize(T *thePlayer, int theNumberOfPlayers){ int n = theNumberOfPlayers;//竞赛者的数量 if (n < 2)//如果竞赛者的数目小于2,不能进行竞赛 throw illegalParameterValue("must have at least 2 players"); //初始化类内数据成员 this->player = thePlayer; //竞赛者 this->numberOfPlayers = n;//当前竞赛者的数目 delete[] this->tree; //删除竞赛树 this->tree = new int[n]; //创建竞赛树数组 //计算s=2^log (n-1) int i, s; for (s = 1; 2 * s <= n - 1; s += s); this->lowExt = 2 * (n - s);//最底层外部节点个数(见公式) this->offset = 2 * s - 1;//固定值(见公式) //为最低级别的外部节点进行匹配 for (i = 2; i <= this->lowExt; i += 2) play((this->offset + i) / 2, i - 1, i); //处理剩余的外部节点 if (n % 2 == 1) { //特殊情况下奇数n,发挥内部和外部节点 play(n / 2, this->tree[n - 1], this->lowExt + 1); i = this->lowExt + 3; } else { i = this->lowExt + 2; } //i是最左边剩余的外部节点 for (; i <= n; i += 2) play((i - this->lowExt + n - 1) / 2, i - 1, i);}/* 对tree[p]节点进行比赛,leftChild为左子节点,rightChild为右子节点 如果还有父节点,继续向上比赛*/template<class T>void completeWinnerTree<T>::play(int p, int leftChild, int rightChild){ //因为为最小赢者树,所以返回值比较小的为赢者 this->tree[p] = (this->player[leftChild] <= this->player[rightChild]) ? leftChild : rightChild; //如果是右子节点并且还有父节点,那么就继续向上进行比赛 while ((p % 2 == 1) && (p > 1)) { //对父节点进行比赛 this->tree[p / 2] = (this->player[tree[p - 1]] <= this->player[tree[p]]) ? tree[p - 1] : tree[p]; p /= 2;//移至父节点 }}//在参赛者thePLayer的分数变化后重赛template<class T>void completeWinnerTree<T>::rePlay(int thePlayer){ int n = numberOfPlayers;//竞赛者的数量 if (thePlayer <= 0 || thePlayer > n) throw illegalParameterValue("Player index is illegal"); int matchNode, // 将在其中进行下一场比赛的节点 leftChild, // 比赛节点的左孩子 rightChild; // 比赛节点的右孩子 // 查找第一个匹配节点及其子节点 if (thePlayer <= lowExt) {//从最低层次开始 matchNode = (offset + thePlayer) / 2; leftChild = 2 * matchNode - offset; rightChild = leftChild + 1; } else { matchNode = (thePlayer - lowExt + n - 1) / 2; if (2 * matchNode == n - 1) { leftChild = tree[2 * matchNode]; rightChild = thePlayer; } else { leftChild = 2 * matchNode - n + 1 + lowExt; rightChild = leftChild + 1; } } tree[matchNode] = (player[leftChild] <= player[rightChild]) ? leftChild : rightChild; // 第二次比赛的特殊情况 if (matchNode == n - 1 && n % 2 == 1) { matchNode /= 2; // 移至父节点 tree[matchNode] = (player[tree[n - 1]] <= player[lowExt + 1]) ? tree[n - 1] : lowExt + 1; } // 玩剩下的比赛 matchNode /= 2; // 移至父节点 for (; matchNode >= 1; matchNode /= 2) tree[matchNode] = (player[tree[2 * matchNode]] <= player[tree[2 * matchNode + 1]]) ? tree[2 * matchNode] : tree[2 * matchNode + 1];}//输出赢者树中的一些信息template<class T>void completeWinnerTree<T>::output()const{ std::cout << "number of players = " << this->numberOfPlayers << " lowExt = " << this->lowExt << " offset = " << this->offset << std::endl; //输出每一个节点的赢者 std::cout << "complete winner tree pointers are" << std::endl; for (int i = 1; i < this->numberOfPlayers; i++) std::cout << this->tree[i] << ' '; std::cout << std::endl;}#endif
struct player{ int id, key; operator int() const { return key; }};int main(){ //输入竞赛者的数量 int n; std::cout << "Enter number of players, >= 2" << std::endl; std::cin >> n; if (n < 2){ std::cout << "Bad input" << std::endl; exit(1); } //创建竞赛者数组 player *thePlayer = new player[n+1]; std::cout << "Create players success" << std::endl; //输入每一个竞赛者的键值 std::cout << "Enter player values" << std::endl; for (int i = 1; i <= 10; i++) { std::cin >> thePlayer[i].key; thePlayer[i].id = i; } //创建一个赢者树 completeWinnerTree<player> *w = new completeWinnerTree<player>(thePlayer, n); std::cout << "Create completeWinnerTree success" << std::endl; //输出最终的赢者 std::cout << "The winner tree is" << std::endl; w->output(); //改变一个节点的值,然后重新进行比赛 thePlayer[2].key = 0; w->rePlay(2); std::cout << "Changed player 2 to zero, new tree is" << std::endl; w->output(); //改变一个节点的值,然后重新进行比赛 thePlayer[3].key = -1; w->rePlay(3); std::cout << "Changed player 3 to -1, new tree is" << std::endl; w->output(); //改变一个节点的值,然后重新进行比赛 thePlayer[7].key = 2; w->rePlay(7); std::cout << "Changed player 7 to 2, new tree is" << std::endl; w->output(); return 0;}
【数据结构】第五章——树与二叉树详细介绍树的基本概念、重要术语以及一些基本性质……
Huffman树(哈夫曼树)又称最优二叉树,是一种带权路径长度最短的二叉树,常用于信息传输、数据压缩等方面。它的构造基于字符出现的频率,通过将频率较低的字符组合在一起,最终形成一棵树。在Huffman树中,每个叶节点代表一个字符,而每个字符的编码则是从根节点到叶节点的路径所对应的二进制序列。
二叉查找树(Binary Search Tree,简称BST)是一种常用的数据结构,它能够高效地进行查找、插入和删除操作。二叉查找树的特点是,对于树中的每个节点,其左子树中的所有节点都小于该节点,而右子树中的所有节点都大于该节点。
目录树树的概念树的存储与表示常见的一些树的应用场景二叉树二叉树的概念二叉树的性质(特性)二叉树的实现二叉树添加结点二叉树的遍历广度优先遍历(层次遍历)深度优先遍历二叉树由遍历确定一个树树二维树的概念树(英语:tree)是一种抽象数据类型(ADT)或是实作这种抽象数据类型的数据结构,用来模拟具有树状结构性质的数据集合。它是由n(n>=1)个有限节点组成一个具有层次关系的集合。把它叫做“树”是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。它具有以下的特点:每个节点有零个或多个子节
一、概述1、树的概念树(英语:tree)是一种抽象数据类型(ADT)或是实作这种抽象数据类型的数据结构,用来模拟具有树状结构性质的数据集合。它是由n(n>=1)个有限节点组成一个具有层次关系的集合。把它叫做“树”是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。它具有以下的特点:每个节点有零个或多个子节点;没有父节点的节点称为根节点;每一个非根节点有且只有一个父节点;除了根节点外
一、分裂树简介当使用AVL树或红黑树来实现字典时,最坏情况下,每一个字典操作的时间复杂性是字典大小的对数。在已知的数据结构中,没有一个会提供更好的性能。然而,在字典的很多实际应用中,令我们更感兴趣的不是一个操作而是一个操作序列所需要的时间。例如,在前面搜索树的应用文章中,每一个应用的时间复杂性都取决于一个字典操作序列,而不是任意一个操作分裂树概述分裂树是二叉搜索树,而且是一个单独的字典...
树是一种非线性的数据结构,它包含n(n>=1)个节点,(n-1)条边的有穷集合。把它叫做“树”是因为它看起来像一个倒挂的树,也就是说它是根朝上,叶子朝下的。
树型结构是一类重要的非线性结构,树型结构是结点之间有分支, 并且具有层次关系的结构,它非常类似于自然界中的树
树在数据结构是一个极其重要的存在,例如二叉树,排序二叉树,平衡二叉树,红黑树等等在许多项目中运用比较广,而且也是平时考察的重点,所以今天就来系统地谈一谈树树定义:n个结点的有限集合,当n等于0时,称为空树,n个结点的树只有n-1条边,有如下性质。有且仅有一个特定的称为根的结点当n>1时,其余结点可分为m个互不相交的有限集合,其中每一个集合本身又是一颗树,称为根节点的子树(n个结点的树中只有n-1条边)树中的一个结点的子结点的个数称为该结点的度,树中最大度数称为树的度度大于0
二叉搜索树树概念二叉树常见二叉树分类完全二叉树满二叉树平衡二叉树二叉搜索树红黑树二叉树搜索树实现实际应用哈夫曼编码红黑树树概念树状图是一种数据结构,它是由 n(n>=1)个有限结点组成一个具有层次关系的集合。把它叫做“树”是因 为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。它具
1. 树与树的表示1.1 什么是树1.2 查找1.2.1 静态查找1.3 树的定义1.4 树的一些基本术语1.5 树的表示2. 二叉树及存储结构2.1 二叉树的定义3. 二叉树的遍历1. 树与树的表示1.1 什么是树 树是一种数据结构,它是由n(n>=1)个有限节点组成一个具有层次关系的集合。把它叫做“树”是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。 树具有以下的特点: (1)每个节点有零个或多个子节点; (2)没有父节点的节点称为根节点; (3)每一个非根.
一、索引顺序访问方法当字典足够小时,可以整个驻留在内存
树的定义树是n个结点的有限集,当n=0的时候称为空树。有且仅有一个特定的称为根的结点。树的度就是树内各个结点的度的最大值。度为0的结点称为叶结点。度不为0的结点称为分支结点。树的存储结构三种不同的表示结构:双亲表示法,孩子表示法,孩子兄弟表示法。双亲表示法 每个结点除了知道自己是谁以外,还知道其双亲在哪里。 #define MAX_TREE_SIZE ...
第一个位置放弃不用。那么线段树就遵循如下规律。父节点索引: i 父节点的左节点: i。2 父节点的右节点:i。
# 数据结构与算法:树的基本概念与练习## 引言在数据结构与算法中,树是一种重要的非线性数据结构。树由节点组成,节点之间通过边连接。树结构在众多计算机科学领域中具有广泛的应用,包括数据库、文件系统、网络路由等。本文将探讨树的基本概念,并通过示例和习题加深理解。## 树的基本定义树是由一个根节点和若干子节点组成的层次结构。树的基本术语包括:- **节点**:树中的每个元素称为节点
前面说的链表、栈、队列都是线性结构,而树是一个非线性节点。 树简介 树是一种非线性结构,由一个根节点和若干
1)结点的度:树所拥有的子树叫做树的度2)树的度:就是树中节点度最大的度3)树的层次:根为第一层次4)树的深度:指数的层次最大的5)二叉树:第i层上最多有2^(i-1)个节点 深度为k的数最多有2^k -1个节点 任何一颗二叉树,如果终端节点数为n1, 结点
本篇为在leetcode等平台刷题过程中遇到的典型例题及自己的学习笔记,会随着学习进程不断更新,题目都借鉴自网络或书籍,仅用作个人学习。由于水平实在有限,不免产生谬误,欢迎读者多多批评指正。如需要转载请与博主联系,谢谢 本篇为在leetcode和牛客等平台刷题过程中遇到的典型例题及自己的学习笔记,会随着学习进程不断更新,题目都借鉴自网络或书籍,仅用作个人
近日,欧洲知名企业级前端框架 Vaadin 正式发布了 官
MATLAB与人工智能:深度学习实战入门摘要: 随着Deep Learning Toolbox的成熟,MATLAB已成为一个强大的AI开发平台。本文将通过一个图像分类的实例,引导读者快速上手在MATLAB中构建和训练一个简单的卷积神经网络。人工智能,特别是深度学习,正在重塑各行各业。MATLAB通过 ...
在分析科学的漫长链条中,样品前处理始终是决定最终结果准确性与可靠性的关键环节,也是制约实验室效率的“瓶颈”。传统湿法消解方法耗时冗长、试剂消耗大、人为误差风险高,且易造成挥发性元素损失。如今,以微波消解工艺为核心的现代化消解仪,改变这一传统流程,将实验室带入了高效、安全、环保的新时代。一、 效率的提 ...
前言 最近一直在AI辅助编程工具的发展,特别是Claude Code这个工具。经过两个月的实际使用,想和大家分享一些使用心得和技术观察。 开发中的常见痛点 作为开发者,我们在日常工作中经常遇到这些情况: 接手新项目时,代码结构复杂,理解成本高 重构老代码时,担心引入新的bug 编写重复性代码,效 ...