数据结构算法-树的技术点

树的描述

在这里插入图片描述

从图中不难发现 这是一种树,并且还是倒挂的树, 生活当中的族谱 ,前段时间的从鱼进化为人类过程 ,员工进阶
那些具备经济实力的公司的旗下的子公司 比如说 字节和他的子公司 .等等,
这就是生活当中的树 C++的子类也是树

树的原理

树是由n个有限结点组成层次关系的集合 这是一种树,并且还是倒挂的树,也就是从根 朝上,叶 朝下

树可以由多个节点组成
如下图所示:
在这里插入图片描述

树会有以下特点:
每个结点都必须零个或者多个子结点 没有父节点则称为根结点 每一个非根结点都仅有一个父节点 根节点除此之外
每个子结点可以包含多个不相交子结点

根节点(root): 顶层

在这里插入图片描述

孩子结点(Child): 一个结点含有的子树的根结点称为该结点的子结点

在这里插入图片描述

叶子结点(Leaf):没有孩子的结点

在这里插入图片描述

度 (Degree):一个结点包含子树的数量

  • 78的度
    在这里插入图片描述

  • 93的度
    在这里插入图片描述

  • 92的度
    在这里插入图片描述

  • 59的度
    在这里插入图片描述

  • 96的度
    在这里插入图片描述

  • 叶子结点度为0

边(Edge): 一个结点连接到另一个结点称为边

在这里插入图片描述

深度(Depth):根节点到该节点边的数量

在这里插入图片描述

节点高度(Height):当前结点到叶子结点 边的数量

  • 78的高度
    在这里插入图片描述

93的高度
在这里插入图片描述

层级(Level):节点到根节点最长路径边的总数量

在这里插入图片描述

路径(Path):一个节点到另一个节点经过的边

在这里插入图片描述

二叉树的描述

在这里插入图片描述

相当于给树来个计划生育

二叉树的原理

二叉树只允许最多两个节点 二叉树节点最多有两个节点 并不是一定要有两个分支节点
如图所示:
在这里插入图片描述

  • 在非空的二叉树里,具有i-1层的节点的总数不超过2的i-1次方 i>=1
    在这里插入图片描述

  • 深度为h-1的二叉树 最多有二的h次方 -1个结点 最少有h个结点

在这里插入图片描述

在这里插入图片描述

  • 对任意一颗二叉树 若叶子节点的数量表示为N0度数为二的树数量 为表示为N2N0=N2+1;
    在这里插入图片描述

若像单传那样n2=0 n1表示单传 根节点 只有一个子节点
,若其中有一个有俩节点 则n2+1;

在这里插入图片描述

在这里插入图片描述

常见二叉树分类

完全二叉树

  • 最后一层的最后一个节点 可有可无 其他的都是满的 才叫 完全二叉树:
    • 叶子节点必须从左到右排列 右子树叶子节点 必须右缺 不能左缺

在这里插入图片描述

错误的完全二叉树:
在这里插入图片描述

完全二叉树的应用:

满二叉树

  • 也就是叶子结点全部都存在
    • ,并且左子树右子树都必须是

在这里插入图片描述

平衡二叉树

  • 树的两个子树的高度差绝对值不能超过1
    • 而且还得看 左右子树两个子树的高度差绝对值不能超过1
      在这里插入图片描述

二叉搜索树

  • 二叉搜索树 也叫二叉排序树
    • 若左子树不为空 左子树均小于或者等于根节点
    • 若右子树不为空 右子树均大于或者等于根节点
      在这里插入图片描述

红黑树

  • 带有颜色属性的平衡二叉搜索树

    • 节点的颜色属性是黑色或者红色
    • 根节点是黑色
    • 所有的叶子节点都是黑色
    • 每个红色节点必须有两个黑色节点
    • 黑色节点的子节点可红可黑
    • 红色节点的子节点必须是黑色节点

注意:不允许红色节点拥有两个连续红色子节点
在这里插入图片描述

  • 错误的红黑树
    在这里插入图片描述

  • 任何非叶子节点到其每个叶子节点的所有简单路径都包含相同数目黑色节点

在这里插入图片描述

  • 右子树比左子树 的数目多出两倍

  • 不同的黑色节点 添加一个红色节点

为啥使用二叉搜索树

就像是电商里商品价格如下:
在这里插入图片描述

如果挨个去查找 9.9 元的 小零食效率很显然 ,现在很明显是在第2位置 如何大大的提高呢

先排序 价格 再来查找 你会发现不一样的美观 强迫症患者的福报,简直是

经过排序:
在这里插入图片描述

再用二分查找算法 怎么一查找就非常快 , 原理非常简单 就是从中间开始,如果 查找值 这个中间的比要小 那么排除中间+的数据 直接往左 直到找到 为止,否则往右查找

二叉搜索树 就是非常符合查找数据 而且 也是两个分支一个左,右分支

也非常复合人的特征 大脑分为左,右脑 ,手分为左,右手 脚分为左,右脚

二叉搜索树存储方式

那采用什么方式存储,如果是用顺序存储二叉树 那就是堆 ?

存储方式:链式存储
二叉搜索树节点 在这里插入图片描述
这个二叉搜索树和链表不一样 很明显 在这里LeftChild,RightChild 分别指向会 LeftChild,RightChild 分支 在二叉树的描述…

二叉搜索树算法

二叉搜索树的结构

using TreeKey = user defined;
// 树节点 = 二叉搜索树节点
using TreeNode = struct _BinarySearchTreeNode;

struct _BinarySearchTreeNode{
	TreeKey value;//tree value
	TreeNode* LeftChild;//左孩子
	TreeNode* RightChild;//右孩子
};
//二叉搜索树
struct BinarySearchTree {
	TreeNode* Root;//树的根节点
	size_t size;// 二叉搜索树的节点个数
};

二叉搜索树算法声明

#ifndef __BINARY_SEARCH_TREE_H__
#define	__BINARY_SEARCH_TREE_H__

using TreeKey = = user defined;;
using TreeNode = struct _BinarySearchTreeNode;

struct _BinarySearchTreeNode{
	TreeKey value;
	TreeNode* LeftChild;
	TreeNode* RightChild;
};

struct BinarySearchTree {
	TreeNode* Root;//树的根节点
	size_t size;// 二叉搜索树的节点个数
};

//查找当前结点中最大或者最小值
struct FindCurrentNodeMaxOrMinValue{

	TreeKey* MaxOrnMinValue;
	bool isExist;
}; 

//查找二叉搜索树结点 类型
struct FindTreeNode_type {

	TreeNode* Node;
	bool isExist;
};

//查找二叉搜索树value类型
struct FindTreeValue_type {

	TreeKey* value;
	bool isExist;
};


//二叉搜索树删除算法类型
enum class BinarySearchTreeDeletionAlgorithmType{

	Loop,//用循环来删除
	Recursive, //用递归来删除
};


//二叉搜索树删除算法类型
using BSTDeleteAlgorithmType = BinarySearchTreeDeletionAlgorithmType;


//二叉搜索树查找算法类型
enum class BinarySearchTreeSearchAlgorithmType {

	Loop,//用循环来查找
	Recursive, //用递归来查找
};

//二叉搜索树查找算法类型
using BSTSearchAlgorithmType = BinarySearchTreeSearchAlgorithmType;

//二叉搜索树遍历算法类型
enum class  BinarySearchTreeTraversalAlgorithmType {
	Recursive,
	NoRecursive
};
//二叉搜索树遍历算法类型
using BSTTraversalAlgorithmType = BinarySearchTreeTraversalAlgorithmType;

//初始化二叉搜索树
void InitBinarySearchTree(BinarySearchTree& Tree, TreeNode  * const &InitRoot = nullptr);


//初始化二叉搜索树
void  BinarySearchTree_Build(BinarySearchTree& Tree, const TreeKey* const array,  int arraySize);

//插入数据到二叉搜索树
void BinarySearchTree_Insert(BinarySearchTree& tree, const TreeKey& value);

//从二叉搜索树中删除指定的元素
bool BinarySearchTree_Erase(BinarySearchTree& tree, const TreeKey& Key, BSTDeleteAlgorithmType Defaultdelete = BSTDeleteAlgorithmType::Loop);

//二叉搜索树搜索指定元素
FindTreeValue_type BinarySearchTree_Search(BinarySearchTree& tree, const TreeKey& Key,  BSTSearchAlgorithmType DefaultSearch = BSTSearchAlgorithmType::Loop);

//先序遍历
void FirstOrderTraversal(BinarySearchTree& tree, BSTTraversalAlgorithmType DefaultTraversal= BSTTraversalAlgorithmType::NoRecursive);

//中序遍历
void InOrderTraversal(BinarySearchTree& tree, BSTTraversalAlgorithmType DefaultTraversal = BSTTraversalAlgorithmType::NoRecursive);

//后序遍历
void LastOrderTraversal(BinarySearchTree& tree, BSTTraversalAlgorithmType DefaultTraversal = BSTTraversalAlgorithmType::NoRecursive);

//层序遍历
void LevelOrderTraversal(BinarySearchTree& tree);

//销毁二叉搜索树
void DestroyBinarySearchTree(BinarySearchTree& tree);
//按照值查找节点
FindTreeNode_type BinarySearchTree_FindTreeNode(TreeNode*& RootNode, const TreeKey& Key);
//按照值查找当前节点的父节点
FindTreeNode_type BinarySearchTree_FindTreeParentNode(TreeNode*& RootNode, const TreeKey& Key);

// 查找当前节点最大值或者最小值
FindCurrentNodeMaxOrMinValue BinarySearchTree_FindMaxOrMinValue(TreeNode*& Currentnode);
#endif

二叉搜索树初始化

void InitBinarySearchTree(BinarySearchTree& Tree, TreeNode* const& InitRoot){

	Tree.Root = InitRoot;
	Tree.size = 0u;
}

二叉搜索树构建算法

void  BinarySearchTree_Build(BinarySearchTree& Tree, const TreeKey *const array, int arraySize){
	
	
	if (arraySize>0 && array)	{

		InitBinarySearchTree(Tree);
		auto First = array;
		auto Last = array + arraySize;

		while (First!=Last){
			auto &value = *First++;
			BinarySearchTree_Insert(Tree, value);
		}

	}
}

二叉搜索树插入算法

思维导图

在这里插入图片描述

流程图

在这里插入图片描述

void BinarySearchTree_Insert(BinarySearchTree & tree, const TreeKey & value) {

	//创建二叉树搜索树节点
	TreeNode* newTreeNode = CreateBnarySearchTreeNode(value);
	//判断是否是空树 树根节点是不是空
	const bool  isRootNodeEmpty = tree.Root;
	if (!isRootNodeEmpty) {
		tree.Root = newTreeNode;
	}

	TreeNode* currentNode = tree.Root;

	if (isRootNodeEmpty) {

		TreeNode* InsertNode = nullptr;
		while (currentNode) {
			InsertNode = currentNode;
			if (newTreeNode->value < currentNode->value) {

				currentNode = currentNode->LeftChild;
			}
			else {
				currentNode = currentNode->RightChild;
			}
		}

		const bool isLertInsert = newTreeNode->value < InsertNode->value;

		if (isLertInsert) {
			InsertNode->LeftChild = newTreeNode;
		}
		else {
			InsertNode->RightChild = newTreeNode;
		}

	}

	++tree.size;

}

二叉搜索树删除算法

通过递归

递归删除算法图

在这里插入图片描述

递归删除二叉搜索树的节点算法

static  FindCurrentNodeMaxOrMinValue BinarySearchTree_FindMax(TreeNode*& Currentnode) {
	FindCurrentNodeMaxOrMinValue find{ 0 };
	TreeNode* CurrentNode = Currentnode;
	if (CurrentNode) {
		if (CurrentNode->RightChild) {
			CurrentNode = CurrentNode->RightChild;

			find = { &CurrentNode->value ,(bool)CurrentNode };
		}
	}
	return find;
}

static TreeNode* Recursive_EraseTreeNode(TreeNode* &Root, const TreeKey& Key, TreeNode*& deleteNode) {

	if (!Root){
		return nullptr;
	}

	if (Root->value > Key) {
		Root->LeftChild = Recursive_EraseTreeNode(Root->LeftChild, Key, deleteNode);
		return Root;
	}
	if (Root->value < Key) {
		Root->RightChild = Recursive_EraseTreeNode(Root->RightChild, Key, deleteNode);
		return Root;
	}
	deleteNode = Root;

	if (!Root->LeftChild && !Root->RightChild) {


		Root = nullptr;
		return Root;
	}

	if ((!Root->LeftChild && Root->RightChild)) {

		return Root->RightChild;

	}

	if (Root->LeftChild && !Root->RightChild) {

		return Root->LeftChild;
	}

	auto FIndRet = BinarySearchTree_FindMax(Root);
	if (FIndRet.isExist){
		Root->value = *FIndRet.MaxOrnMinValue;
	}

	Root->RightChild = Recursive_EraseTreeNode(Root->RightChild, *FIndRet.MaxOrnMinValue, deleteNode);
	return Root;
}

通过循环

bool IsSame(TreeNode*& Target, TreeNode*& Source) {
	return Target == Source;
 }

void DestroyTreeNode(TreeNode*& treeNode,  const  TreeNode*const &where = nullptr) {
	delete treeNode;
	treeNode = (decltype(treeNode))where;
}

void  unlinkTreeNodeLeftChild(TreeNode*& TargetNode, TreeNode* SourceNode=nullptr) {
	TargetNode ? TargetNode->LeftChild = SourceNode : TargetNode;
}

void unlinkTreeNodeRightChild(TreeNode*& TargetNode,  TreeNode * SourceNode = nullptr) {
	TargetNode ?  TargetNode->RightChild= SourceNode : TargetNode;
}

FindTreeNode_type BinarySearchTree_FindTreeNode(TreeNode*& RootNode, const TreeKey& Key){

	FindTreeNode_type FindRet{ 0 };
	auto currentNode = RootNode;
	if (currentNode) {

		while (currentNode && currentNode->value != Key) {
			if (!(Key < currentNode->value) ){
				currentNode = currentNode->RightChild;
			}
			else {
				currentNode = currentNode->LeftChild;
			}
		}
		if (currentNode) {

			FindRet = { currentNode,(bool)currentNode };

		}
	}

	return FindRet;
}

FindTreeNode_type BinarySearchTree_FindTreeParentNode(TreeNode*& RootNode, const TreeKey& Key) {

	FindTreeNode_type FindRet{ 0 };
	auto currentNode = RootNode;
	if (currentNode) {
		FindRet.isExist = true;
		while (currentNode && currentNode->value != Key) {
			FindRet.Node = currentNode;

			if (currentNode->value > Key) {
				currentNode = currentNode->LeftChild;
			}
			else {
				currentNode = currentNode->RightChild;
			}
		}
		FindRet.isExist = currentNode != nullptr ? FindRet.isExist : !FindRet.isExist;
	}

	return FindRet;
}

FindCurrentNodeMaxOrMinValue BinarySearchTree_FindMaxOrMinValue(TreeNode*& Currentnode){
	FindCurrentNodeMaxOrMinValue find{ 0 };
	TreeNode* CurrentNode = Currentnode;
	if (CurrentNode)	{
		if (CurrentNode->LeftChild){
			CurrentNode = CurrentNode->LeftChild;
			while (CurrentNode->RightChild){
			CurrentNode = CurrentNode->RightChild;
			}
			find = { &CurrentNode->value ,(bool)CurrentNode };
		}
		 
		else if (CurrentNode->RightChild) {
		
			CurrentNode = CurrentNode->RightChild;

			while (CurrentNode->LeftChild){
				CurrentNode = CurrentNode->LeftChild;
			}

			find = { &CurrentNode->value ,(bool)CurrentNode };
		}
	}
	return find;
}

bool Loop_EraseTreeNode(BinarySearchTree& tree, const TreeKey& Key) {
	

	FindTreeNode_type FindCurrent = BinarySearchTree_FindTreeNode(tree.Root, Key);
	FindTreeNode_type FindCurrentParent = BinarySearchTree_FindTreeParentNode(tree.Root, Key);

	if (FindCurrent.isExist) {

		if (!FindCurrent.Node->LeftChild && !FindCurrent.Node->RightChild) {
			if (!IsSame(FindCurrent.Node, tree.Root)) {
				if (FindCurrentParent.isExist) {

					if (IsSame(FindCurrentParent.Node->LeftChild, FindCurrent.Node)) {
						unlinkTreeNodeLeftChild(FindCurrentParent.Node);
					}
					else {
						unlinkTreeNodeRightChild(FindCurrentParent.Node);
					}
				}
			}
			else {
				tree.Root = nullptr;
			}

			DestroyTreeNode(FindCurrent.Node);

		}
		else if (FindCurrent.Node->LeftChild && !FindCurrent.Node->RightChild) {

			if (!IsSame(FindCurrent.Node, tree.Root)) {
				if (FindCurrentParent.isExist) {

					if (IsSame(FindCurrentParent.Node->LeftChild, FindCurrent.Node)) {
						FindCurrentParent.Node->LeftChild = FindCurrent.Node->LeftChild;
					}
					else{
						FindCurrentParent.Node->RightChild = FindCurrent.Node->LeftChild;
					}
					unlinkTreeNodeLeftChild(FindCurrent.Node);
				}
			}

			else {
				(tree.Root = tree.Root->LeftChild);
			}
			DestroyTreeNode(FindCurrent.Node);
		}
		else if (FindCurrent.Node->RightChild && !FindCurrent.Node->LeftChild) {

			if (!IsSame(FindCurrent.Node, tree.Root)) {
				if (FindCurrentParent.isExist) {

					if (IsSame(FindCurrentParent.Node->LeftChild, FindCurrent.Node)) {
						(FindCurrentParent.Node->LeftChild = FindCurrent.Node->RightChild);
					}
					else {
						(FindCurrentParent.Node->RightChild = FindCurrent.Node->RightChild);
					}
					unlinkTreeNodeRightChild(FindCurrent.Node);
				}
			}
			else {
				(tree.Root = tree.Root->RightChild);
			}
			
			DestroyTreeNode(FindCurrent.Node);
		}
		else{
			auto MaxOrMinKey = BinarySearchTree_FindMaxOrMinValue(FindCurrent.Node);
			FindTreeNode_type DeleteCurrent = BinarySearchTree_FindTreeNode(tree.Root, *MaxOrMinKey.MaxOrnMinValue);
			FindTreeNode_type DeleteCurrentParent = BinarySearchTree_FindTreeParentNode(tree.Root, *MaxOrMinKey.MaxOrnMinValue);
			FindCurrent.isExist = MaxOrMinKey.isExist;
			if (FindCurrent.isExist){
				
				FindCurrent.isExist = DeleteCurrentParent.Node;
				FindCurrent.Node->value = *MaxOrMinKey.MaxOrnMinValue;
				if (FindCurrent.isExist){
					if (IsSame(DeleteCurrentParent.Node->LeftChild, DeleteCurrent.Node)){
						if (DeleteCurrent.Node->RightChild && !DeleteCurrent.Node->LeftChild) {
							(DeleteCurrentParent.Node->LeftChild = DeleteCurrent.Node);
						}
						else{
							unlinkTreeNodeLeftChild(DeleteCurrentParent.Node);
						}
					}
					else if (IsSame(DeleteCurrentParent.Node->RightChild, DeleteCurrent.Node)){
						if (DeleteCurrent.Node->LeftChild && !DeleteCurrent.Node->RightChild){
							(DeleteCurrentParent.Node->LeftChild = DeleteCurrent.Node->LeftChild);
						}
						else {
							unlinkTreeNodeRightChild(DeleteCurrentParent.Node);
						}
					}

					unlinkTreeNodeLeftChild(DeleteCurrent.Node);
					unlinkTreeNodeRightChild(DeleteCurrent.Node);

					DestroyTreeNode(DeleteCurrent.Node);
				}
			}

		}

		--tree.size;

	}
	return FindCurrent.isExist;
}

二叉搜索树删除算法实现

bool BinarySearchTree_Erase(BinarySearchTree& tree, const TreeKey& Key, BSTDeleteAlgorithmType Defaultdelete){
	
	bool ret = false;

	switch (Defaultdelete)	{

	case BSTDeleteAlgorithmType::Loop:
		ret = Loop_EraseTreeNode(tree, Key);
		break;
	case BSTDeleteAlgorithmType::Recursive:
		TreeNode* deleteNode = nullptr;
		Recursive_EraseTreeNode(tree.Root, Key, deleteNode);
		if (deleteNode){
			DestroyTreeNode( deleteNode);
			--tree.size;
			ret = true;
			break;
		}			
	}
	return ret;
}

二叉搜索树查找算法

通过递归

FindTreeValue_type BinarySearchTree_RecursiveSearch(TreeNode*& RootNode, const TreeKey& Key){

	FindTreeValue_type find = {};
	if (RootNode==nullptr||RootNode->value==Key)	{
		find = { RootNode ? &RootNode->value : nullptr,(bool)RootNode };
	}
	else if (Key<RootNode->value){
		find = BinarySearchTree_RecursiveSearch(RootNode->LeftChild, Key);
	}else{
		find = BinarySearchTree_RecursiveSearch(RootNode->RightChild, Key);
	}

	return find;
}

通过循环

FindTreeValue_type BinarySearchTree_LoopSearch(TreeNode*& RootNode, const TreeKey& Key){
	
		FindTreeValue_type FindRet{ 0 };
		auto currentNode = RootNode;
		if (currentNode) {

			while (currentNode && currentNode->value != Key) {
				if (currentNode->value > Key) {
					currentNode = currentNode->LeftChild;
				}
				else {
					currentNode = currentNode->RightChild;
				}
			}
			if (currentNode) {
				FindRet = { &currentNode->value,(bool)currentNode };
			}
		}

		return FindRet;
}

二叉搜索树查找算法实现

FindTreeValue_type BinarySearchTree_Search(BinarySearchTree& tree, const TreeKey& Key, BSTSearchAlgorithmType DefaultSearch){

	const  int LestIndex = (int)BSTSearchAlgorithmType::Recursive + 1;
	const decltype(&BinarySearchTree_LoopSearch)Search[LestIndex]{BinarySearchTree_LoopSearch,BinarySearchTree_RecursiveSearch };
	const int SearchIndex = (int)DefaultSearch % LestIndex;
	return Search[SearchIndex](tree.Root, Key);
	
}

二叉搜索树遍历算法

//先序遍历
void FirstOrderTraversal(BinarySearchTree& tree, BSTTraversalAlgorithmType DefaultTraversal) {

	constexpr decltype(&FirstOrderNonRecursiveTraversal) Traversal[] = { FirstOrderRecursiveTraversal,FirstOrderNonRecursiveTraversal };
	constexpr int LastIndex = sizeof(Traversal) / sizeof(*Traversal);
	const auto str = DefaultTraversal == BSTTraversalAlgorithmType::Recursive ? "递归" : "非递归";
	cout << "<" << str << "先序遍历> :";

	const int TraversalIndex = (int)DefaultTraversal % LastIndex;

	Traversal[TraversalIndex](tree.Root);

	cout << "<null>" << endl;
}
//中序遍历
void InOrderTraversal(BinarySearchTree& tree, BSTTraversalAlgorithmType DefaultTraversal) {

	constexpr decltype(&FirstOrderNonRecursiveTraversal) Traversal[] = { InOrderRecursiveTraversal,InOrderNonRecursiveTraversal };
	constexpr int LastIndex = sizeof(Traversal) / sizeof(*Traversal);

	const auto str = DefaultTraversal == BSTTraversalAlgorithmType::Recursive ? "递归" : "非递归";
	cout << "<" << str << "中序遍历> :";
	const int TraversalIndex = (int)DefaultTraversal % LastIndex;

	Traversal[TraversalIndex](tree.Root);

	cout << "<null>" << endl;
}

//后序遍历
void LastOrderTraversal(BinarySearchTree& tree, BSTTraversalAlgorithmType DefaultTraversal) {

	constexpr decltype(&LastOrderNonRecursiveTraversal) Traversal[] = { LastOrderRecursiveTraversal,LastOrderNonRecursiveTraversal };
	constexpr int LastIndex = sizeof(Traversal) / sizeof(*Traversal);

	const auto str = DefaultTraversal == BSTTraversalAlgorithmType::Recursive ? "递归" : "非递归";
	cout << "<" << str << "后序遍历> :";
	
	const int TraversalIndex = (int)DefaultTraversal % LastIndex;

	Traversal[TraversalIndex](tree.Root);

	cout << "<null>" << endl;
}

递归遍历

前序遍历

在这里插入图片描述

指定的二叉搜索树的递归遍历
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  1. 蓝色的虚线连接线表示:调用函数
  2. 黑色的虚线连接线表示返回到上一个结点

递归调用栈

在这里插入图片描述

递归先序遍历 代码执行过程图

执行 根 和 左子树

在这里插入图片描述

执行右子树

在这里插入图片描述

执行右子树 并且返回根节点

在这里插入图片描述

先根 再左 后右 递归前序遍历顺口溜

//递归前序遍历 根 -> 左 -> 右
void FirstOrderRecursiveTraversal(TreeNode*& Root) {
	if (Root) {
		cout <<" "<< Root->value << " ->";

		FirstOrderRecursiveTraversal(Root->LeftChild);
		FirstOrderRecursiveTraversal(Root->RightChild);
	}
}

中序遍历

在这里插入图片描述

指定的二叉搜索树递归遍历
在这里插入图片描述
在这里插入图片描述

先左 再根 后右 递归中序遍历顺口溜

//递归中序遍历
void InOrderRecursiveTraversal(TreeNode*& Root) {
	if (Root) {
		InOrderRecursiveTraversal(Root->LeftChild);

		cout << " " << Root->value << " ->";

		InOrderRecursiveTraversal(Root->RightChild);
	}
}

后序遍历

在这里插入图片描述

先左 再右 后根 递归后序遍历顺口溜


//递归后序遍历
void  LastOrderRecursiveTraversal(TreeNode*& Root) {

	if (Root) {
		LastOrderRecursiveTraversal(Root->LeftChild);
		LastOrderRecursiveTraversal(Root->RightChild);
		cout << " " << Root->value << " ->";
	}
}


非递归遍历

前序遍历

在这里插入图片描述

//非递归先序遍历
static void FirstOrderNonRecursiveTraversal(TreeNode*& Root) {

	SeqStack Stack;
	initStack(Stack);

	auto CurrentNode = Root;
	push_Stack(Stack, CurrentNode);
	while (!emptyStack(Stack)) {

		CurrentNode = TopStack(Stack);
		cout << " " << CurrentNode->value << "-> ";
		pop_Stack(Stack);
		if (CurrentNode->RightChild) {
			push_Stack(Stack, CurrentNode->RightChild);
		}
		if (CurrentNode->LeftChild) {
			push_Stack(Stack, CurrentNode->LeftChild);
		}
	}

	destroyStack(Stack);
}

中序遍历

在这里插入图片描述

//非递归中序遍历
static void InOrderNonRecursiveTraversal(TreeNode*& Root) {

	SeqStack Stack;
	initStack(Stack);
	//cout << "<中序遍历> :" 
	auto CurrentNode = Root;
	while (!emptyStack(Stack) || CurrentNode) {

		while (CurrentNode) {
			push_Stack(Stack, CurrentNode);
			CurrentNode = CurrentNode->LeftChild;
		}

		CurrentNode = TopStack(Stack);
		cout << " " << CurrentNode->value << "-> ";
		pop_Stack(Stack);
		CurrentNode = CurrentNode->RightChild;
	}

	//cout << "<null>" << endl;
	destroyStack(Stack);
}

后序遍历

在这里插入图片描述

//非递归后序遍历
void  LastOrderNonRecursiveTraversal(TreeNode*& Root) {

	SeqStack Stack;
	initStack(Stack);
	auto CurrentNode = Root;
	decltype(CurrentNode) leafNode = nullptr;
	bool  isleafNode;
	push_Stack(Stack, CurrentNode);

	while (!emptyStack(Stack)) {


		CurrentNode = TopStack(Stack);

		isleafNode = (!CurrentNode->LeftChild && !CurrentNode->RightChild) || (leafNode != nullptr && (leafNode == CurrentNode->LeftChild || leafNode == CurrentNode->RightChild));
		if (isleafNode) {

			pop_Stack(Stack);
			leafNode = CurrentNode;
			cout << " " << CurrentNode->value << "-> ";
		}
		else {
			
			if (CurrentNode->RightChild) {
				push_Stack(Stack, CurrentNode->RightChild);
			}

			if (CurrentNode->LeftChild) {
				push_Stack(Stack, CurrentNode->LeftChild);
			}
		}
	}
	//cout << "<null>" << endl;
	destroyStack(Stack);
}

层序遍历

一层一层的遍历 直到 没有为止 相当于先序遍历

void LevelOrderTraversal(BinarySearchTree& tree) {

	cout << "<层序遍历> :";
	SeqQueue Queue;
	initQueue(Queue);
	auto CurrentNode = tree.Root;
	push_Queue(Queue, CurrentNode);
	while (!emptyQueue(Queue)) {

		CurrentNode = Queue_front(Queue);
		cout << CurrentNode->value << "-> ";
		pop_Queue(Queue);

		if (CurrentNode->LeftChild) {
			push_Queue(Queue, CurrentNode->LeftChild);
		}
		if (CurrentNode->RightChild) {
			push_Queue(Queue, CurrentNode->RightChild);
		}
	}
	cout << "<null>" << endl;
	destroyQueue(Queue);

}

销毁 二叉搜索树
根据只能用递归后序遍历来销毁 非递归不可以的

void DestroyBinarySearchTree(TreeNode* root) {
	if (root) {

		if (!root->LeftChild && !root->RightChild) {
			delete root;
		}
		else {
			if (root->LeftChild) {
				DestroyBinarySearchTree(root->LeftChild);
			}
			if (root->RightChild) {
				DestroyBinarySearchTree(root->RightChild);
			}
		}
	}
}


void DestroyBinarySearchTree(BinarySearchTree& tree) {

	DestroyBinarySearchTree(tree.Root);
	tree = {};
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小森程序员

若能帮助到你,小费自愿付费

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值