26 Star 369 Fork 112

cyberdash / 数据结构(C++模板实现)

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
binary_tree.h 52.16 KB
一键复制 编辑 原始数据 按行查看 历史
Y_Dash 提交于 2023-06-24 15:55 . BinaryTree增加doxygen
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475
/*!
* @file binary_tree.h
* @author CyberDash计算机考研, cyberdash@163.com(抖音id:cyberdash_yuan)
* @brief 二叉树模板类
* @version 0.2.1
* @date 2020-11-01
*/
#ifndef CYBER_DASH_BINARY_TREE_H
#define CYBER_DASH_BINARY_TREE_H
#include <iostream>
#include <cstdlib>
#include <stack>
#include <queue>
#include "binary_tree.h"
using namespace std;
/*!
* @brief **二叉树结点模板结构体**
* @tparam TData 数据项类型模板参数
*/
template <typename TData>
struct BinaryTreeNode {
/*! @brief **默认构造函数** */
BinaryTreeNode() : left_child(NULL), right_child(NULL) {}
/*! @brief **构造函数(数据项, 左右孩子)** */
explicit BinaryTreeNode(TData data, BinaryTreeNode<TData>* left_child = NULL, BinaryTreeNode<TData>* right_child = NULL)
: data(data), left_child(left_child), right_child(right_child) {}
TData data; //!< **数据项**
BinaryTreeNode<TData>* left_child; //!< **左孩子结点**(指针)
BinaryTreeNode<TData>* right_child; //!< **右孩子结点**(指针)
};
/*!
* @brief <b>(后序遍历)回溯栈结点模板类</b>
* @tparam TData 数据项类型模板参数
* @note
* (后序遍历)回溯栈结点模板类
* ----------------------
* ----------------------
*
* <span style="color:#D40000;font-size:larger">
* 仅用于后序遍历\n\n 回溯栈需要记录栈内结点是从左子树回溯, 还是右子树回溯\n
* </span>
*
* ----------------------
*/
template <typename TData>
struct PostorderBacktrackStackNode {
/*!
* @brief **构造函数(二叉树结点)**
* @param node 二叉树结点
* @note
* 构造函数(二叉树结点)
* -----------------
* -----------------
*
* <span style="color:#DF5A00;font-size:larger">
* 默认tag是左子树回溯
* </span>
*
* -----------------
* 初始化node, tag设置为LEFT_BACK_TRACKING(左孩子回溯)
*/
explicit PostorderBacktrackStackNode(BinaryTreeNode<TData>* node = NULL) : node(node), tag(LEFT_BACK_TRACKING) {}
BinaryTreeNode<TData>* node; //!< **二叉树结点指针**
enum { LEFT_BACK_TRACKING = 0, RIGHT_BACK_TRACKING } tag; //!< **标签**, 0: 左孩子回溯, 1: 右孩子回溯
};
template <typename TData> class BinaryTree;
// 判断两颗树相同
template<typename TData> bool operator==(const BinaryTree<TData>& binary_tree_1, const BinaryTree<TData>& binary_tree_2);
// 输出二叉树
template<typename TData> ostream& operator<<(ostream& out, BinaryTree<TData>& binary_tree);
/*!
* @brief **二叉树模板类**
* @tparam TData 数据项类型模板参数
*/
template <typename TData>
class BinaryTree {
public:
/*! @brief **默认构造函数** */
BinaryTree() : root_(NULL) {}
/*!
* @brief **构造函数(根结点数据项)**
* @note
* 构造函数(根结点数据项)
* ------------------
* ------------------
*
* ------------------
* 对root_调用InsertInSubTreeRecursive_
*
*
* ------------------
*/
explicit BinaryTree(const TData& data) { this->InsertInSubtreeRecursive_(this->root_, data); }
// 复制构造函数
BinaryTree(const BinaryTree<TData>& src_binary_tree);
/*!
* @brief **析构函数**
* @note
* 析构函数
* ------
* ------
*
* <span style="color:#D40000;font-size:larger">
* I have bad news for you
* </span>
*
* ------
* 对root_调用RemoveSubtreeRecursive_
*
*
* ------
*/
~BinaryTree() { this->DeleteSubtreeRecursive_(root_); }
/*! @brief **获取根节点** */
BinaryTreeNode<TData>* Root() const { return this->root_; }
/*! @brief **判断是否为空树** */
bool IsEmpty() { return this->root_ == NULL; }
/*!
* @brief **获取父结点**
* @param node 结点
* @return 父结点
* @note
* 获取父结点
* --------
* --------
*
* --------
* **if** this->root_ == NULL || this->root_ == node :\n
* &emsp; 返回NULL\n
* **else** :\n
* &emsp; 返回this->GetParentInSubtreeRecursive_(this->root_, node)\n
*
*
* --------
*/
BinaryTreeNode<TData>* Parent(BinaryTreeNode<TData>* node) const {
return (this->root_ == NULL || this->root_ == node) ? NULL : this->GetParentInSubtreeRecursive_(this->root_, node);
}
/*!
* @brief **获取高度**
* @return 高度
* 获取高度
* ------------
* ------------
*
* ------------
* 调用HeightOfSubtreeRecursive_
*
*
* ------------
*/
int Height() { return this->HeightOfSubtreeRecursive_(this->root_); }
/*!
* @brief **获取结点数**
* @return 结点数
* @note
* 获取结点数
* ------------
* ------------
*
* ------------
* 调用SizeOfSubTreeRecursive_
*
*
* ------------
*/
int Size() { return this->SizeOfSubTreeRecursive_(this->root_); }
/*!
* @brief **插入结点(递归)**
* @param data 数据项
* @return 是否成功
* @note
* 插入节点(递归)
* ------------
* ------------
*
* ------------
* 调用InsertInSubtreeRecursive_
*
*
* ------------
*/
bool InsertRecursive(const TData& data) { return this->InsertInSubtreeRecursive_(this->root_, data); }
/*!
* @brief **是否存在数据**
* @param data 数据项
* @return 是否存在
* @note
* 是否存在数据
* ----------
* ----------
*
* ----------
* 调用ExistInSubTree_
*
*
* ----------
*/
bool Exist(TData data) { return this->ExistInSubTree_(this->root_, data); }
/*!
* @brief **前序遍历(递归)**
* @param visit 结点访问函数
* @note
* 前序遍历(递归)
* ------------
* ------------
*
* ------------
* 调用PreorderTraversalOfSubtreeRecursive_
*
*
* ------------
*/
void PreorderTraversalRecursive(void (*visit)(BinaryTreeNode<TData>*)) {
this->PreorderTraversalOfSubtreeRecursive_(this->root_, visit);
}
/*!
* @brief **前序遍历**
* @param visit 结点访问函数
* @note
* 前序遍历
* -------
* -------
*
* -------
* 调用PreorderTraversalOfSubtree_
*
*
* -------
*/
void PreorderTraversal(void (*visit)(BinaryTreeNode<TData>*)) {
this->PreorderTraversalOfSubtree_(this->root_, visit);
}
/*!
* @brief **中序遍历(递归)**
* @param visit 结点访问函数
* @note
* 中序遍历(递归)
* -----------
* -----------
*
* -----------
* 调用InorderTraversalOfSubtreeRecursive_
*
*
* -----------
*/
void InorderTraversalRecursive(void (*visit)(BinaryTreeNode<TData>* node)) {
this->InorderTraversalOfSubtreeRecursive_(this->root_, visit);
}
/*!
* @brief **中序遍历**
* @param visit 结点访问函数
* @note
* 中序遍历
* ------
* ------
*
* ------
* 调用InorderTraversalOfSubtree_
*
*
* ------
*/
void InorderTraversal(void (*visit)(BinaryTreeNode<TData>* node)) {
this->InorderTraversalOfSubtree_(this->root_, visit);
}
/*!
* @brief **后序遍历(递归)**
* @param visit 结点访问函数
* @note
* 后序遍历(递归)
* -----------
* -----------
*
* -----------
* 调用PostorderTraversalOfSubtreeRecursive_
*
*
* -----------
*/
void PostorderTraversalRecursive(void (*visit)(BinaryTreeNode<TData>*)) {
this->PostorderTraversalOfSubtreeRecursive_(this->root_, visit);
}
/*!
* @brief **后序遍历**
* @param visit 结点访问函数
* @note
* 后序遍历
* ------
* ------
*
* ------
* 调用PostorderTraversalOfSubtree_
*
*
* ------
*/
void PostorderTraversal(void (*visit)(BinaryTreeNode<TData>*)) {
this->PostorderTraversalOfSubtree_(this->root_, visit);
}
/*!
* @brief **层序遍历**
* @param Visit 结点访问函数
* @note
* 层序遍历
* ------
* ------
*
* ------
* 调用LevelOrderTraversalOfSubtree_
*
*
* ------
*/
void LevelOrderTraversal(void (*Visit)(BinaryTreeNode<TData>*)) {
this->LevelOrderTraversalOfSubtree_(this->root_, Visit);
}
/*!
* @brief **建树(by前序遍历和中序遍历)**
* @param preorder_list 前序遍历列表
* @param inorder_list 中序遍历列表
* @param length 字符串长度
* @return 执行结果
* @note
* 建树(by前序遍历和中序遍历)
* ----------------------
* ----------------------
*
* ----------------------
* 调用CreateSubtreeByPreorderAndInorderList_\n
*
*
* ----------------------
*/
bool CreateByPreorderAndInorderList(TData* preorder_list, TData* inorder_list, int length) {
bool res = this->CreateSubtreeByPreorderAndInorderList_(preorder_list, inorder_list, length, this->root_);
return res;
}
/*!
* @brief **打印**
* @note
* 打印
* ---
* ---
*
* ---
* 对root_调用PrintSubTreeRecursive_
*
*
* ---
*/
void Print() { this->PrintSubTreeRecursive_(this->root_); };
// 判断两颗二叉树是否相同(递归)
static bool Equal(BinaryTreeNode<TData>* root1, BinaryTreeNode<TData>* root2);
protected:
BinaryTreeNode<TData>* root_; //!< **根结点**
// 子树插入结点(递归)
bool InsertInSubtreeRecursive_(BinaryTreeNode<TData>*& subtree_root, const TData& data);
// 子树删除(递归)
void DeleteSubtreeRecursive_(BinaryTreeNode<TData>*& subtree_root);
// 子树是否存在数据(递归)
bool ExistInSubTree_(BinaryTreeNode<TData>* subtree_root, TData data) const;
// 复制(递归)
bool DuplicateSubTreeRecursive_(BinaryTreeNode<TData>* src_subtree_root, BinaryTreeNode<TData>*& target_subtree_root);
// 求子树的高度(递归)
int HeightOfSubtreeRecursive_(BinaryTreeNode<TData>* subtree_root) const;
// 求子树的Size(递归)
int SizeOfSubTreeRecursive_(BinaryTreeNode<TData>* subtree_root) const;
// 子树获取节点的父节点
BinaryTreeNode<TData>* GetParentInSubtreeRecursive_(BinaryTreeNode<TData>* subtree_root, BinaryTreeNode<TData>* node) const;
// 子树前序遍历(递归)
void PreorderTraversalOfSubtreeRecursive_(BinaryTreeNode<TData>* subtree_root, void (*visit)(BinaryTreeNode<TData>*));
// 子树前序遍历
void PreorderTraversalOfSubtree_(BinaryTreeNode<TData>* subtree_root, void (*visit)(BinaryTreeNode<TData>*));
// 子树中序遍历(递归)
void InorderTraversalOfSubtreeRecursive_(BinaryTreeNode<TData>* subtree_root, void (*visit)(BinaryTreeNode<TData>*));
// 子树中序遍历
void InorderTraversalOfSubtree_(BinaryTreeNode<TData>* subtree_root, void (*visit)(BinaryTreeNode<TData>*));
// 子树后序遍历(递归)
void PostorderTraversalOfSubtreeRecursive_(BinaryTreeNode<TData>* subtree_root, void (*visit)(BinaryTreeNode<TData>*));
// 子树后序遍历
void PostorderTraversalOfSubtree_(BinaryTreeNode<TData>* subtree_root, void (*visit)(BinaryTreeNode<TData>*));
// 子树层序遍历
void LevelOrderTraversalOfSubtree_(BinaryTreeNode<TData>* subtree_root, void (*Visit)(BinaryTreeNode<TData>*));
// 子树打印
void PrintSubTreeRecursive_(BinaryTreeNode<TData>* subtree_root);
// 使用前序遍历和中序遍历结果, 创建子树(递归)
bool CreateSubtreeByPreorderAndInorderList_(TData* preorder_sub_list,
TData* inorder_sub_list,
int length,
BinaryTreeNode<TData>*& subtree_root);
// 判断两颗树相同
friend bool operator== <>(const BinaryTree<TData>& binary_tree_1, const BinaryTree<TData>& binary_tree_2);
// 输出二叉树
friend ostream& operator<< <>(ostream& out, BinaryTree<TData>& binary_tree);
};
/*!
* @brief **复制构造函数**
* @tparam TData 数据项类型模板参数
* @param src_binary_tree 源二叉树
* @note
* 复制构造函数
* ----------
* ----------
*
* ----------
* 调用DuplicateSubTreeRecursive_\n
* **if** 调用失败 :\n
* &emsp; 抛出logic_error\n
*
*
* ----------
*/
template<typename TData>
BinaryTree<TData>::BinaryTree(const BinaryTree<TData>& src_binary_tree) {
bool res = DuplicateSubTreeRecursive_(src_binary_tree.Root(), this->root_); // 调用DuplicateSubTreeRecursive_
if (!res) { // if 调用失败
throw logic_error("DuplicateSubTreeRecursive_ error"); // 抛出logic_error
}
}
/*!
* @brief **子树插入结点(递归)**
* @tparam TData 数据项类型模板参数
* @param subtree_root 子树根结点
* @param data 结点数据项
* @return 执行结果
* @note
* 子树插入结点(递归)
* ---------------
* ---------------
*
* ---------------
* + **1 空子树处理**\n
* **if** 空子树 :\n
* &emsp; subtree_root分配内存并初始化\n
* &emsp; **if** 分配内存失败 :\n
* &emsp;&emsp; 抛出bad_alloc()\n
* &emsp; 返回true\n\n
* + **2 分治递归**\n
* 计算left_subtree_height(左子树高度)\n
* 计算right_subtree_height(右子树高度)\n\n
* **if** left_subtree_height > right_subtree_height :\n
* &emsp; 左子树递归调用InsertInSubtreeRecursive_\n
* &emsp; **if** 调用失败 :\n
* &emsp;&emsp; 返回false\n
* **else** \n
* &emsp; 右子树递归调用InsertInSubtreeRecursive_\n
* &emsp; **if** 调用失败 :\n
* &emsp;&emsp; 返回false\n\n
* + **3 退出函数**\n
* 返回true\n
*
*
* ---------------
*/
template<typename TData>
bool BinaryTree<TData>::InsertInSubtreeRecursive_(BinaryTreeNode<TData>*& subtree_root, const TData& data) {
// ---------- 1 空子树处理 ----------
if (subtree_root == NULL) { // if 空子树
subtree_root = new BinaryTreeNode<TData>(data); // subtree_root分配内存并初始化
if (subtree_root == NULL) { // if 分配内存失败
throw bad_alloc(); // 抛出bad_alloc()
}
return true; // 返回true
}
// ---------- 2 分治递归 ----------
int left_subtree_height = HeightOfSubtreeRecursive_(subtree_root->left_child); // 计算left_subtree_height(左子树高度)
int right_subtree_height = HeightOfSubtreeRecursive_(subtree_root->right_child); // 计算right_subtree_height(右子树高度)
if (left_subtree_height > right_subtree_height) { // if left_subtree_height > right_subtree_height
bool res = InsertInSubtreeRecursive_(subtree_root->right_child, data); // 左子树递归调用InsertInSubtreeRecursive_
if (!res) { // if 调用失败
return false; // 返回false
}
} else { // else
bool res = InsertInSubtreeRecursive_(subtree_root->left_child, data); // 右子树递归调用InsertInSubtreeRecursive_
if (!res) { // if 调用失败
return false; // 返回false
}
}
// ---------- 3 退出函数 ----------
return true; // 返回true
}
/*!
* @brief **子树删除(递归)**
* @param subtree_root 子树根节点
* @note
* 子树删除(递归)
* -----------
* -----------
*
* -----------
* + **1 空子树处理**\n
* **if** subtree_root为NULL :\n
* &emsp; 退出函数\n\n
* + **2 分治递归**\n
* 左子树递归删除\n
* 右子树递归删除\n\n
* + **3 删除子树根结点**\n
* 释放subtree_root\n
* subtree_root置NULL\n
*
*
* -----------
*/
template <typename TData>
void BinaryTree<TData>::DeleteSubtreeRecursive_(BinaryTreeNode<TData>*& subtree_root) {
// ---------- 1 空子树处理 ----------
if (subtree_root == NULL) { // if subtree_root为NULL
return; // 退出函数
}
// ---------- 2 分治递归 ----------
this->DeleteSubtreeRecursive_(subtree_root->left_child); // 左子树递归删除
this->DeleteSubtreeRecursive_(subtree_root->right_child); // 右子树递归删除
// ---------- 3 删除子树根结点 ----------
delete subtree_root; // 释放subtree_root
subtree_root = NULL; // subtree_root置NULL
}
/**
* @brief **子树是否存在数据(递归)**
* @tparam TData 数据项类型模板参数
* @param subtree_root 子树根结点
* @param data 数据项值
* @return 是否存在
* @note
* 子树是否存在数据(递归)
* ------------------
* ------------------
*
* ------------------
* + **1 空树处理**\n
* **if** 空树 :\n
* &emsp; 返回false\n\n
* + **2 存在条件处理**\n
* **if** 子树根结点data等于参数data :\n
* &emsp; 返回true\n\n
* + **3 分治递归**\n
* 左子树递归\n
* **if** 存在 :\n
* &emsp; 返回true\n\n
* 右子树递归\n
* **if** 存在 :\n
* &emsp; 返回true\n\n
* + **4 退出函数**\n
* 返回false\n
*
*
* ------------------
*/
template<typename TData>
bool BinaryTree<TData>::ExistInSubTree_(BinaryTreeNode<TData>* subtree_root, TData data) const {
// ---------- 1 空树处理 ----------
if (subtree_root == NULL) { // if 空树
return false; // 返回false
}
// ---------- 2 存在条件处理 ----------
if (subtree_root->data == data) { // if 子树根结点data等于参数data
return true; // 返回true
}
// ---------- 3 分治递归 ----------
bool existed = ExistInSubTree_(subtree_root->left_child, data); // 左子树递归
if (existed) { // if 存在
return true; // 返回true
}
existed = ExistInSubTree_(subtree_root->right_child, data); // 右子树递归
if (existed) { // if 存在
return true; // 返回true
}
// ----------4 退出函数 ----------
return false; // 返回false
}
/*!
* @brief **复制(递归)**
* @tparam TData 数据项类型模板参数
* @param src_subtree_root 源子树根结点
* @param target_subtree_root 目标子树根结点
* @return 执行结果
* @note
* 复制(递归)
* --------
* --------
*
* --------
* + **1 空源子树处理**\n
* **if** src_subtree_root(源子树根结点) == NULL :\n
* &emsp; target_subtree_root(目标子树根结点) = NULL\n
* &emsp; 返回true\n\n
* + **2 目标子树根结点处理**\n
* target_subtree_root分配内存并初始化\n
* **if** 内存分配失败 :\n
* &emsp; 返回false\n\n
* + **3 分治递归**\n
* 左子树递归复制\n
* **if** 失败 :\n
* &emsp; 返回false\n\n
* 右子树递归复制\n
* **if** 失败 :\n
* &emsp; 返回false\n\n
* + **4 退出函数**\n
* 返回true\n
*
*
* --------
*/
template<typename TData>
bool BinaryTree<TData>::DuplicateSubTreeRecursive_(BinaryTreeNode<TData>* src_subtree_root,
BinaryTreeNode<TData>*& target_subtree_root)
{
// ---------- 1 空源子树处理 ----------
if (src_subtree_root == NULL) { // if src_subtree_root(源子树根结点) == NULL
target_subtree_root = NULL; // target_subtree_root(目标子树根结点) = NULL
return true; // 返回true
}
// ---------- 2 目标子树根结点处理 ----------
target_subtree_root = new BinaryTreeNode<TData>(src_subtree_root->data); // target_subtree_root分配内存并初始化
if (!target_subtree_root) { // if 内存分配失败
return false; // 返回false
}
// ---------- 3 分治递归 ----------
bool res = this->DuplicateSubTreeRecursive_(src_subtree_root->left_child, // 左子树递归复制
target_subtree_root->left_child);
if (!res) { // if 失败
return false; // 返回false
}
res = this->DuplicateSubTreeRecursive_(src_subtree_root->right_child, // 右子树递归复制
target_subtree_root->right_child);
if (!res) { // if 失败
return false; // 返回false
}
// ---------- 4 退出函数 ----------
return true; // 返回true
}
/*!
* @brief **求子树高度(递归)**
* @tparam TData 数据项类型模板参数
* @param subtree_root 子树根结点
* @return 子树高度
* @note
* 求子树高度(递归)
* --------------
* --------------
*
* --------------
* + **1 空子树处理**\n
* **if** 空子树 :\n
* &emsp; 返回0\n\n
* + **2 分治递归**\n
* 左子树递归, 得到left_subtree_height(左子树高度)\n
* 右子树递归, 得到left_subtree_height(右子树高度)\n\n
* 计算subtree_height, 等于1 + 最高子树的高度\n\n
* + **3 返回结果**\n
* 返回subtree_height\n
*
*
* --------------
*/
template<typename TData>
int BinaryTree<TData>::HeightOfSubtreeRecursive_(BinaryTreeNode<TData>* subtree_root) const {
// ---------- 1 空子树处理 ----------
if (subtree_root == NULL) { // if 空子树
return 0; // 返回0
}
// ---------- 2 分治递归 ----------
int left_subtree_height = HeightOfSubtreeRecursive_(subtree_root->left_child); // 左子树递归, 得到left_subtree_height(左子树高度)
int right_subtree_height = HeightOfSubtreeRecursive_(subtree_root->right_child); // 右子树递归, 得到left_subtree_height(右子树高度)
// 计算subtree_height, 等于1 + 最高子树的高度
int subtree_height = (left_subtree_height < right_subtree_height ? right_subtree_height : left_subtree_height) + 1;
// ---------- 3 返回结果 ----------
return subtree_height; // 返回subtree_height
}
/*!
* @brief **子树size(递归)**
* @tparam TData 数据项类型模板参数
* @param subtree_root 子树根结点
* @return 子树size
* @note
* 子树size(递归)
* -------------
* -------------
*
* -------------
* + **1 空子树处理**\n
* **if** 空子树 :\n
* &emsp; 返回0\n\n
* + **2 分治递归**\n
* 左子树递归, 得到left_subtree_size(左子树size)\n
* 右子树递归, 得到right_subtree_size(右子树size)\n\n
* 计算subtree_size, 等于1 + left_subtree_size + right_subtree_size\n\n
* + **3 返回结果**\n
* 返回subtree_size\n
*
*
* -------------
*/
template<typename TData>
int BinaryTree<TData>::SizeOfSubTreeRecursive_(BinaryTreeNode<TData>* subtree_root) const {
// ---------- 1 空子树处理 ----------
if (subtree_root == NULL) { // if 空子树
return 0; // 返回0
}
// ---------- 2 分治递归 ----------
int left_subtree_size = SizeOfSubTreeRecursive_(subtree_root->left_child); // 左子树递归, 得到left_subtree_size(左子树size)
int right_subtree_size = SizeOfSubTreeRecursive_(subtree_root->right_child); // 右子树递归, 得到right_subtree_size(右子树size)
int subtree_size = 1 + left_subtree_size + right_subtree_size; // 计算subtree_size, 等于1 + left_subtree_size + right_subtree_size
// ---------- 3 返回结果 ----------
return subtree_size; // 返回subtree_size
}
/*!
* @brief **在子树内获取父结点(递归)**
* @tparam TData 数据项类型模板参数
* @param subtree_root 子树根结点
* @param node 结点
* @return 父结点
* @note
* 在子树内获取父结点()
* ---------------
* ---------------
*
* ---------------
* + **1 空子树处理**\n
* **if** 空子树 :\n
* &emsp; 返回NULL\n\n
* + **2 找到父节点情况处理**\n
* **if** node是subtree_root的左孩子或者右孩子 :\n
* &emsp; 返回subtree_root\n\n
* + **3 分治递归**\n
* 左子树递归调用ParentInSubtree_\n
* **if** 未找到父节点 :\n
* &emsp; 右子树递归调用ParentInSubtree_\n
* 返回调用结果\n
*
*
* ---------------
*/
template<typename TData>
BinaryTreeNode<TData>* BinaryTree<TData>::GetParentInSubtreeRecursive_(BinaryTreeNode<TData>* subtree_root,
BinaryTreeNode<TData>* node) const
{
// ---------- 1 空子树处理 ----------
if (subtree_root == NULL) { // if 空子树
return NULL; // 返回NULL
}
// ---------- 2 找到父节点情况处理 ----------
if (subtree_root->left_child == node || subtree_root->right_child == node) { // if node是subtree_root的左孩子或者右孩子
return subtree_root; // 返回subtree_root
}
// ---------- 3 分治递归 ----------
BinaryTreeNode<TData>* parent = GetParentInSubtreeRecursive_(subtree_root->left_child, node); // 左子树递归调用ParentInSubtree_
if (parent == NULL) { // if 未找到父节点
parent = GetParentInSubtreeRecursive_(subtree_root->right_child, node); // 右子树递归调用ParentInSubtree_
}
return parent; // 返回调用结果
}
/*!
* @brief **子树前序遍历(递归)**
* @tparam TData 数据项类型模板参数
* @param subtree_root 子树根结点
* @param visit 访问函数
* @note
* 子树前序遍历(递归)
* ---------------
* ---------------
*
* ---------------
* + **1 空子树处理**\n
* **if** 空子树 :\n
* &emsp; 返回\n\n
* + **2 分治递归**\n
* 访问subtree_root\n\n
* 左子树递归\n
* 右子树递归\n
*
*
* ---------------
*/
template<typename TData>
void BinaryTree<TData>::PreorderTraversalOfSubtreeRecursive_(BinaryTreeNode<TData>* subtree_root,
void (*visit)(BinaryTreeNode<TData>*))
{
// ---------- 1 空子树处理 ----------
if (subtree_root == NULL) { // if 空子树
return; // 返回
}
// ---------- 2 分治递归 ----------
visit(subtree_root); // 访问subtree_root
PreorderTraversalOfSubtreeRecursive_(subtree_root->left_child, visit); // 左子树递归
PreorderTraversalOfSubtreeRecursive_(subtree_root->right_child, visit); // 右子树递归
}
/**
* @brief **子树前序遍历(非递归)**
* @tparam TData 数据项类型模板参数
* @param subtree_root 子树根结点
* @param visit 访问函数
* @note
* 子树前序遍历(非递归)
* -----------------
* -----------------
*
* -----------------
* 声明backtrack_stack(回溯栈)\n
* subtree_root(子树根结点)入栈\n\n
* **while loop** 回溯栈不为空 :\n
* &emsp; 取栈顶, 赋给cur\n
* &emsp; 栈顶出栈\n\n
* &emsp; 访问cur\n\n
* &emsp; **if** cur存在右孩子 :\n
* &emsp;&emsp; cur右孩子入栈\n
* &emsp; **if** cur存在左孩子 :\n
* &emsp;&emsp; cur左孩子入栈\n
*
*
* -----------------
*/
template<typename TData>
void BinaryTree<TData>::PreorderTraversalOfSubtree_(BinaryTreeNode<TData>* subtree_root,
void (*visit)(BinaryTreeNode<TData>*))
{
stack<BinaryTreeNode<TData>*> backtrack_stack; // 声明backtrack_stack(回溯栈)
backtrack_stack.push(subtree_root); // subtree_root(子树根结点)入栈
while (!backtrack_stack.empty()) { // while loop 回溯栈不为空
BinaryTreeNode<TData>* cur = backtrack_stack.top(); // 取栈顶, 赋给cur
backtrack_stack.pop(); // 栈顶出栈
visit(cur); // 访问cur
if (cur->right_child != NULL) { // if cur存在右孩子
backtrack_stack.push(cur->right_child); // cur右孩子入栈
}
if (cur->left_child != NULL) { // if cur存在左孩子
backtrack_stack.push(cur->left_child); // cur左孩子入栈
}
}
}
/*!
* @brief **子树中序遍历(递归)**
* @tparam TData 数据项类型模板参数
* @param subtree_root 子树根结点
* @param visit 访问函数
* @note
* 子树中序遍历(递归)
* ---------------
* ---------------
*
* ---------------
* + **1 空子树处理**\n
* **if** 空子树 :\n
* &emsp; 返回\n\n
* + **2 分治递归**\n
* 左子树递归\n
* 访问subtree_root\n
* 右子树递归\n
*
*
* ---------------
*/
template<typename TData>
void BinaryTree<TData>::InorderTraversalOfSubtreeRecursive_(BinaryTreeNode<TData>* subtree_root,
void (*visit)(BinaryTreeNode<TData>*))
{
// ---------- 1 空子树处理 ----------
if (subtree_root == NULL) { // if 空子树
return; // 返回
}
// ---------- 2 分治递归 ----------
InorderTraversalOfSubtreeRecursive_(subtree_root->left_child, visit); // 左子树递归
visit(subtree_root); // 访问subtree_root
InorderTraversalOfSubtreeRecursive_(subtree_root->right_child, visit); // 右子树递归
}
/**
* @brief **子树中序遍历**
* @tparam TData 数据项类型模板参数
* @param subtree_root 子树根结点
* @param visit 访问函数
* @note
* 子树中序遍历
* ----------
* ----------
*
* ----------
* 声明backtrack_stack(回溯栈)\n
* 初始化cur(当前二叉树结点), 指向subtree_root(子树根结点)\n\n
* **while loop** cur不为NULL || 回溯栈不为空 :\n
* &emsp; **while loop** cur不为NULL :\n
* &emsp;&emsp; cur入栈\n
* &emsp;&emsp; cur指向自身的左孩子\n
* &emsp; **if** 回溯栈不为空 :\n
* &emsp;&emsp; 取栈顶, 赋给cur\n
* &emsp;&emsp; 栈顶出栈\n
* &emsp;&emsp; 访问cur\n
* &emsp;&emsp; cur指向自身右孩子\n
*
*
* ----------
*/
template<typename TData>
void BinaryTree<TData>::InorderTraversalOfSubtree_(BinaryTreeNode<TData>* subtree_root,
void (*visit)(BinaryTreeNode<TData>*))
{
stack<BinaryTreeNode<TData>*> backtrack_stack; // 声明backtrack_stack(回溯栈)
BinaryTreeNode<TData>* cur = subtree_root; // 初始化cur_tree_node(当前二叉树结点), 指向subtree_root(子树根结点)
while (cur != NULL || !backtrack_stack.empty()) { // while loop cur_tree_node不为NULL || 回溯栈不为空
// (一直向左子树方向搜索, 等于在做深度优先搜索DFS)
while (cur != NULL) { // while loop cur_tree_node不为NULL
backtrack_stack.push(cur); // cur_tree_node入栈
cur = cur->left_child; // cur_tree_node指向自身的左孩子
}
if (!backtrack_stack.empty()) { // if 回溯栈不为空
cur = backtrack_stack.top(); // 取栈顶, 赋给cur
backtrack_stack.pop(); // 栈顶出栈
visit(cur); // 访问cur
cur = cur->right_child; // cur指向自身右孩子
}
}
}
/*!
* @brief **子树后序遍历(递归)**
* @tparam TData 数据项类型模板参数
* @param subtree_root 子树根结点
* @param visit 访问函数
* @note
* 子树后序遍历(递归)
* ---------------
* ---------------
*
* ---------------
* + **1 空子树处理**\n
* **if** 空子树 :\n
* &emsp; 返回\n\n
* + **2 分治递归**\n
* 左子树递归\n
* 右子树递归\n
* 访问subtree_root\n
*
*
* ---------------
*/
template<typename TData>
void BinaryTree<TData>::PostorderTraversalOfSubtreeRecursive_(BinaryTreeNode<TData>* subtree_root,
void (*visit)(BinaryTreeNode<TData>*))
{
// ---------- 1 空子树处理 ----------
if (subtree_root == NULL) { // if 空子树
return; // 返回
}
// ---------- 2 分治递归 ----------
PostorderTraversalOfSubtreeRecursive_(subtree_root->left_child, visit); // 左子树递归
PostorderTraversalOfSubtreeRecursive_(subtree_root->right_child, visit); // 右子树递归
visit(subtree_root); // 访问subtree_root
}
/**
* @brief **子树后序遍历**
* @tparam TData 数据项类型模板参数
* @param subtree_root 子树根结点
* @param visit 访问函数
* @note
* 子树后序遍历
* ----------
* ----------
*
* ----------
* 声明backtrack_stack(回溯栈)\n
* 初始化cur_tree_node(当前二叉树结点), 指向subtree_root(子树根结点)\n\n
* **do**:\n\n
* &emsp; <span style="color:#003153">(一直向左子树方向搜索, 等于在做深度优先搜索DFS)</span>\n
* &emsp; **while loop** cur_tree_node不为NULL :\n
* &emsp;&emsp; 使用cur_tree_node初始化栈结点stack_node(默认tag为LEFT_BACK_TRACKING)\n
* &emsp;&emsp; stack_node入栈\n
* &emsp;&emsp; cur_tree_node指向自身的左孩子\n\n
* &emsp; <span style="color:#003153">(标记当前结点尚未开始左侧回溯)</span>\n
* &emsp; 初始化cur_tree_node_left_backtrack_unfinished(当前二叉树结点左侧回溯未完成)为true\n\n
* &emsp; <span style="color:#003153">(分情况处理栈顶, 和维护回溯)</span>\n
* &emsp; **while loop** 初始化cur_tree_node_left_backtrack_unfinished && 回溯栈不为空 :\n
* &emsp;&emsp; 取回溯栈栈顶, 赋给cur_backtrack_node(当前回溯结点)\n
* &emsp;&emsp; 回溯栈栈顶出栈\n
* &emsp;&emsp; 取cur_backtrack_node.node, 给cur_tree_node\n
* &emsp;&emsp; **if** cur_backtrack_node的tag为左侧回溯 :\n
* &emsp;&emsp;&emsp; cur_backtrack_node的tag设为右侧回溯\n
* &emsp;&emsp;&emsp; cur_backtrack_node入栈\n
* &emsp;&emsp;&emsp; cur_tree_node指向自身右孩子\n
* &emsp;&emsp;&emsp; cur_tree_node_left_backtrack_unfinished设为false(表示左侧回溯完成)\n
* &emsp;&emsp; **else** (cur_backtrack_node的tag为右侧回溯) :\n
* &emsp;&emsp;&emsp; 访问cur_tree_node\n\n
* **while loop** 回溯栈不为空\n
*
*
* ----------
*/
template <typename TData>
void BinaryTree<TData>::PostorderTraversalOfSubtree_(BinaryTreeNode<TData>* subtree_root,
void (*visit)(BinaryTreeNode<TData>*))
{
stack<PostorderBacktrackStackNode<TData> > backtrack_stack; // 声明backtrack_stack(回溯栈)
BinaryTreeNode<TData>* cur_tree_node = subtree_root; // 初始化cur_tree_node(当前二叉树结点), 指向subtree_root(子树根结点)
do {
// (一直向左子树方向搜索, 等于在做深度优先搜索DFS)
while (cur_tree_node != NULL) { // while loop cur_tree_node不为NULL
PostorderBacktrackStackNode<TData> stack_node(cur_tree_node); // 使用cur_tree_node初始化栈结点stack_node(默认tag为LEFT_BACK_TRACKING)
backtrack_stack.push(stack_node); // stack_node入栈
cur_tree_node = cur_tree_node->left_child; // cur_tree_node指向自身的左孩子
}
bool cur_tree_node_left_backtrack_unfinished = true; // 初始化cur_tree_node_left_backtrack_unfinished(当前二叉树结点左侧回溯未完成)为true
while (cur_tree_node_left_backtrack_unfinished && !backtrack_stack.empty()) { // while loop 初始化cur_tree_node_left_backtrack_unfinished && 回溯栈不为空
PostorderBacktrackStackNode<TData> cur_backtrack_node = backtrack_stack.top(); // 取回溯栈栈顶, 赋给cur_backtrack_node(当前回溯结点)
backtrack_stack.pop(); // 回溯栈栈顶出栈
cur_tree_node = cur_backtrack_node.node; // 取cur_backtrack_node.node, 给cur_tree_node
if (cur_backtrack_node.tag == PostorderBacktrackStackNode<TData>::LEFT_BACK_TRACKING) { // if cur_backtrack_node的tag为左侧回溯
cur_backtrack_node.tag = PostorderBacktrackStackNode<TData>::RIGHT_BACK_TRACKING; // cur_backtrack_node的tag设为右侧回溯
backtrack_stack.push(cur_backtrack_node); // cur_backtrack_node入栈
cur_tree_node = cur_tree_node->right_child; // cur_tree_node指向自身右孩子
cur_tree_node_left_backtrack_unfinished = false; // cur_tree_node_left_backtrack_unfinished设为false(表示左侧回溯完成)
} else { // else (cur_backtrack_node的tag为右侧回溯)
visit(cur_tree_node); // 访问cur_tree_node
}
}
} while (!backtrack_stack.empty()); // while loop 回溯栈不为空
}
/**
* @brief **子树层序遍历**
* @tparam TData 数据项类型模板参数
* @param subtree_root 子树根结点
* @param Visit 访问函数
* @note
* 子树层序遍历
* ----------
* ----------
*
* ----------
* + **1 初始化遍历队列**\n
* 声明traversal_queue\n
* subtree_root入队\n\n
* + **2 遍历**\n
* **while loop** traversal_queue不为空 :\n
* &emsp; 取队头, 赋给cur\n
* &emsp; 队头出队\n\n
* &emsp; 访问cur\n\n
* &emsp; **if** cur的左孩子不为NULL :\n
* &emsp;&emsp; cur->left_child入队\n
* &emsp; **if** cur的右孩子不为NULL :\n
* &emsp;&emsp; cur->right_child入队\n
*
*
* ----------
*/
template<typename TData>
void BinaryTree<TData>::LevelOrderTraversalOfSubtree_(BinaryTreeNode<TData>* subtree_root,
void (*Visit)(BinaryTreeNode<TData>*))
{
// ---------- 1 初始化遍历队列 ----------
queue<BinaryTreeNode<TData>*> traversal_queue; // 声明traversal_queue
traversal_queue.push(subtree_root); // subtree_root入队
// ---------- 2 遍历 ----------
while (!traversal_queue.empty()) { // while loop traversal_queue不为空
BinaryTreeNode<TData>* cur = traversal_queue.front(); // 取队头, 赋给cur
traversal_queue.pop(); // 队头出队
Visit(cur); // 访问cur
if (cur->left_child != NULL) { // if cur的左孩子不为NULL
traversal_queue.push(cur->left_child); // cur->left_child入队
}
if (cur->right_child != NULL) { // if cur的右孩子不为NULL
traversal_queue.push(cur->right_child); // cur->right_child入队
}
}
}
/*!
* @brief **子树打印(递归)**
* @tparam TData 数据项类型模板参数
* @param subtree_root 子树根结点
* @note
* 子树打印
* -------
* -------
*
* -------
* + **1 空子树处理**\n
* **if** 空子树 :\n
* &emsp; 退出函数\n\n
* + **2 打印子树根结点**\n
* 打印subtree_root->data\n\n
* + **3 递归处理左右子树**\n
* **if** 存在left_child || 存在right_child :\n
* &emsp; 打印'('\n
* &emsp; 对subtree_root->left_child递归调用PrintSubTreeRecursive_\n
* &emsp; 打印','\n
* &emsp; 对subtree_root->right_child递归调用PrintSubTreeRecursive_\n
* &emsp; 打印','\n
*
*
* -------
*/
template<typename TData>
void BinaryTree<TData>::PrintSubTreeRecursive_(BinaryTreeNode<TData>* subtree_root) {
// ---------- 1 空子树处理 ----------
if (subtree_root == NULL) { // if 空子树
return; // 退出函数
}
// ---------- 2 打印子树根结点 ----------
cout << subtree_root->data; // 打印subtree_root->data
// ---------- 3 递归处理左右子树 ----------
if (subtree_root->left_child != NULL || subtree_root->right_child != NULL) { // if 存在left_child || 存在right_child
cout << '('; // 打印'('
this->PrintSubTreeRecursive_(subtree_root->left_child); // 对subtree_root->left_child递归调用PrintSubTreeRecursive_
cout << ','; // 打印','
this->PrintSubTreeRecursive_(subtree_root->right_child); // 对subtree_root->right_child递归调用PrintSubTreeRecursive_
cout << ')'; // 打印','
}
}
/*!
* @brief **创建子树by前序遍历子序列和中序遍历子序列(递归)**
* @tparam TData 数据项类型模板参数
* @param preorder_sub_list 前序遍历子序列
* @param inorder_sub_list 后序遍历子序列
* @param length 子序列长度
* @param subtree_root 子树根结点
* @return 执行结果
* @note
* 创建子树by前序遍历子序列和中序遍历子序列(递归)
* --------------------------------------
* --------------------------------------
*
* <span style="color:#038575;font-size:larger">中序 + 前序: 可以</span> <----- 本函数\n
* <span style="color:#038575;font-size:larger">中序 + 后序: 可以\n</span>
* <span style="color:#D40000;font-size:larger">前序 + 后序: 不可以\n</span>
*
* --------------------------------------
* + **1 空子序列处理**\n
* **if** length == 0 :\n
* &emsp; 返回true\n\n
* + **2 中序序列找到轴, 并生成子树根结点**\n
* 初始化inorder_sub_list_pivot(中序遍历子序列轴)为0\n
* 初始化cur_subtree_root_data, 指向前序遍历序列首元素\n\n
* **while loop** cur_subtree_root_data != inorder_sub_list[inorder_sub_list_pivot] :\n
* &emsp; inorder_sub_list_pivot向后移动1个位置\n\n
* <span style="color:#DF5A00">
* 此时:\n
* &emsp; (preorder_sub_list[1, inorder_sub_list_pivot] / inorder_sub_list[0, inorder_sub_list_pivot - 1])为左子树;\n
* &emsp; inorder_sub_list[inorder_sub_list_pivot]为子树根结点;\n
* &emsp; (preorder_sub_list[inorder_sub_list_pivot + 1, length - 1]/inorder_sub_list[inorder_sub_list_pivot + 1, length - 1])为右子树;\n\n
* </span>
* 使用cur_subtree_root_data, 分配内存并初始化subtree_root\n
* **if** 内存分配失败 :\n
* &emsp; 返回false\n\n
* + **3 递归构造左子树和右子树**\n
* 调用CreateSubtreeByPreorderAndInorderList_, 使用preorder_sub_list[1, inorder_sub_list_pivot] 和 inorder_sub_list[0, inorder_sub_list_pivot - 1], 构造sub_tree的左子树\n
* **if** 构造失败 :\n
* &emsp; 返回false\n\n
* 调用CreateSubtreeByPreorderAndInorderList_, 使用preorder_sub_list[inorder_sub_list_pivot + 1, length - 1] 和 inorder_sub_list[inorder_sub_list_pivot + 1, length - 1], 构造sub_tree的右子树\n
* 返回调用结果\n
*
*
* --------------------------------------
*/
template<typename TData>
bool BinaryTree<TData>::CreateSubtreeByPreorderAndInorderList_(TData* preorder_sub_list,
TData* inorder_sub_list,
int length,
BinaryTreeNode<TData>*& subtree_root)
{
// ---------- 1 空子序列处理 ----------
if (length == 0) { // if length == 0
return true; // 返回true
}
// ---------- 2 中序序列找到轴, 并生成子树根结点 ----------
int inorder_sub_list_pivot = 0; // 初始化inorder_sub_list_pivot(中序遍历子序列轴)为0
TData cur_subtree_root_data = *preorder_sub_list; // 初始化cur_subtree_root_data, 指向前序遍历序列首元素
while (cur_subtree_root_data != inorder_sub_list[inorder_sub_list_pivot]) { // while loop cur_subtree_root_data != inorder_sub_list[inorder_sub_list_pivot]
inorder_sub_list_pivot++; // inorder_sub_list_pivot向后移动1个位置
}
// 此时:
// (preorder_sub_list[1, inorder_sub_list_pivot] / inorder_sub_list[0, inorder_sub_list_pivot - 1])为左子树
// inorder_sub_list[inorder_sub_list_pivot]为子树根结点
// (preorder_sub_list[inorder_sub_list_pivot + 1, length - 1]/inorder_sub_list[inorder_sub_list_pivot + 1, length - 1])为右子树
subtree_root = new BinaryTreeNode<TData>(cur_subtree_root_data); // 使用cur_subtree_root_data, 分配内存并初始化subtree_root
if (subtree_root == NULL) { // if 内存分配失败
return false; // 返回false
}
// ---------- 3 递归构造左子树和右子树 ----------
// 调用CreateSubtreeByPreorderAndInorderList_,
// 使用preorder_sub_list[1, inorder_sub_list_pivot] 和 inorder_sub_list[0, inorder_sub_list_pivot - 1],
// 构造sub_tree的左子树
bool res = CreateSubtreeByPreorderAndInorderList_(preorder_sub_list + 1,
inorder_sub_list,
inorder_sub_list_pivot,
subtree_root->left_child);
if (!res) { // if 构造失败
return false; // 返回false
}
// 调用CreateSubtreeByPreorderAndInorderList_,
// 使用preorder_sub_list[inorder_sub_list_pivot + 1, length - 1]/inorder_sub_list[inorder_sub_list_pivot + 1, length - 1],
// 构造sub_tree的右子树
res = CreateSubtreeByPreorderAndInorderList_(preorder_sub_list + inorder_sub_list_pivot + 1,
inorder_sub_list + inorder_sub_list_pivot + 1,
length - inorder_sub_list_pivot - 1,
subtree_root->right_child);
return res; // 返回调用结果
}
/*!
* @brief **判断两颗二叉树是否相同(递归)**
* @tparam TData 数据项类型模板参数
* @param root1 根节点1
* @param root2 根节点2
* @return 是否相同
* @note
* 判断两颗二叉树是否相同(递归)
* -----------------------
* -----------------------
*
* -----------------------
* + **1 两个空树比较**\n
* **if** root1和root2都为NULL :\n
* &emsp; 返回 true\n\n
* + **2 递归**\n
* **if** root1不为NULL && root2不为NULL && root1->data == root2->data &&
* Equal(root1->left_child, root2->left_child)和Equal(root1->right_child, root2->right_child)都返回true :\n
* &emsp; 返回true\n\n
* + **3 退出函数**\n
* 返回false\n
*
*
* -----------------------
*/
template<typename TData>
bool BinaryTree<TData>::Equal(BinaryTreeNode<TData>* root1, BinaryTreeNode<TData>* root2) {
// ---------- 1 两个空树比较 ----------
if (root1 == NULL && root2 == NULL) { // if root1和root2都为NULL
return true; // 返回 true
}
// ---------- 2 递归 ----------
if (root1 != NULL && root2 != NULL && root1->data == root2->data // if root1不为NULL && root2不为NULL && root1->data == root2->data &&
&& BinaryTree<TData>::Equal(root1->left_child, root2->left_child) // Equal(root1->left_child, root2->left_child)返回true
&& BinaryTree<TData>::Equal(root1->right_child, root2->right_child)) // Equal(root1->right_child, root2->right_child)返回true
{
return true; // 返回true
}
// ---------- 3 退出函数 ----------
return false; // 返回false
}
/*!
* @brief **重载==**
* @tparam TData 数据项类型模板参数
* @param binary_tree_1 二叉树1
* @param binary_tree_2 二叉树2
* @return 结果
* @note
* 重载==
* -----
* -----
*
* -----
* 调用BinaryTree<TData>::Equal(binary_tree_1.Root(), binary_tree_2.Root()), 返回结果\n
*
*
* -----
*/
template<typename TData>
bool operator==(const BinaryTree<TData>& binary_tree_1, const BinaryTree<TData>& binary_tree_2) {
return BinaryTree<TData>::Equal(binary_tree_1.Root(), binary_tree_2.Root());
}
/*!
* @brief **重载&lt;&lt;**
* @tparam TData 数据项类型模板参数
* @param out 输出流
* @param binary_tree 二叉树
* @return 输出流
* @note
* 重载<<
* -----
* -----
*
* 应该使用out, 有兴趣者自行实现:-)
*
* -----
* 调用binary_tree.Print()\n
*
*
* -----
*/
template<typename TData>
ostream& operator<<(ostream& out, BinaryTree<TData>& binary_tree) {
binary_tree.Print();
return out;
}
#endif //CYBER_DASH_BINARY_TREE_H
C++
1
https://gitee.com/cyberdash/data-structures-cpp.git
git@gitee.com:cyberdash/data-structures-cpp.git
cyberdash
data-structures-cpp
数据结构(C++模板实现)
master

搜索帮助