【数据结构】—搜索二叉树(C++实现,超详细!)

这篇具有很好参考价值的文章主要介绍了【数据结构】—搜索二叉树(C++实现,超详细!)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

【数据结构】—搜索二叉树(C++实现,超详细!),高阶数据结构炼体 锻体中,数据结构,算法,c++

                                                      🎬慕斯主页修仙—别有洞天

                                                       ♈️今日夜电波:消えてしまいそうです—真夜中

                                                                1:15━━━━━━️💟──────── 4:18
                                                                    🔄   ◀️   ⏸   ▶️    ☰  

                                      💗关注👍点赞🙌收藏您的每一次鼓励都是对我莫大的支持😍


目录

一、二叉搜索树概念

        什么是二叉搜索树? 

        二叉搜索树的基本操作

二、二叉搜索树的实现

         节点的定义

         二叉搜索树的定义

非递归操作

        插入操作

        查找操作 

        删除操作(重点及难点!!!)

递归法操作 

        中序遍历排升序(经典操作!) 

         插入操作(递归)

         查找操作(递归)

        删除操作(递归) 

 二叉搜索树的应用

        KV模型二叉搜索树

三、整体代码 


一、二叉搜索树概念

        什么是二叉搜索树? 

二叉搜索树(Binary Search Tree,BST)是一种特殊的二叉树,它满足以下几个条件:

  1. 左子树中所有节点的值小于当前节点的值。
  2. 右子树中所有节点的值大于当前节点的值。
  3. 左子树和右子树也都是二叉搜索树。

        二叉搜索树的中序遍历可以得到一个升序的序列,因此它常被用来实现有序集合或映射。在二叉搜索树中,查找、插入和删除操作的时间复杂度通常为O(logn),其中n为树中节点的数量,这得益于二叉搜索树的结构和查找方法。

         如下便是一颗二叉搜索树:

【数据结构】—搜索二叉树(C++实现,超详细!),高阶数据结构炼体 锻体中,数据结构,算法,c++

        一句话总结二叉搜索树:

                左子树节点总是比父节点小,右子树节点总是比父节点大的二叉树。

        二叉搜索树的基本操作

         利用二叉搜索树特性排升序。一听到二叉树,我们通常会想到的是什么?递归!请细细想想我们二叉搜索树的特点->左边的节点总是比父节点小,右边的节点总是比父节点大!那么我们对它使用中序遍历会发生什么呢?还是上面的那颗二叉树,对他进行中序遍历后:

【数据结构】—搜索二叉树(C++实现,超详细!),高阶数据结构炼体 锻体中,数据结构,算法,c++

        中序遍历结果:arr={1,3,4,6,7,8,10,13,14};

二、二叉搜索树的实现

         节点的定义

          说来惭愧作者在此前实现数据结构都是用C语言实现的 o (╥﹏╥)o. ,本文应该是作为作者第一篇用C++实现的数据结构,也算是一个新的起点吧!

        与C语言的区别主要还是在于在此使用struct(实际上是类)可以在定义时就进行初始化,利用的就是类的初始化列表的作用,这就省去了我们C语言时需要额外定义以及调用的初始化操作。只能说有了C++,C语言什么的不认识啦ʅ(´◔౪◔)ʃ

	//节点定义
	template<class K>
	struct BSTreeNode
	{
		BSTreeNode<K>* _left;
		BSTreeNode<K>* _right;
		K _key;

		BSTreeNode(const K& key)
			:_left(nullptr)
			, _right(nullptr)
			, _key(key)
		{}
	};

         二叉搜索树的定义

         对于节点实例化并且重命名,并且给数据进行缺省赋值。

	//二叉搜索树
	template<class K>
	class BSTree
	{
		typedef BSTreeNode<K> Node;
	public:
    //...诸多的操作
	private:
		Node* _root = nullptr;
	};

非递归操作

        插入操作

        插入的具体过程如下:

        a. 树为空,则直接新增节点,赋值给root指针

        b. 树不空,按二叉搜索树性质查找插入位置,插入新节点

【数据结构】—搜索二叉树(C++实现,超详细!),高阶数据结构炼体 锻体中,数据结构,算法,c++

         思路:判断是否为空->是-》直接给根节点赋值->否->进行循环遍历对要插入的值进行“比大小”->大往右,小往左遍历,直到空为止->比较空位置父节点的大小,大插右,小插左

		//插入操作,按照左小右大的规则
		bool Insert(const K& key)
		{
			if (_root == nullptr)
			{
				_root = new Node(key);
				return true;
			}

			Node* parent = nullptr;
			Node* cur = _root;
			while (cur)
			{
				parent = cur;
				if (cur->_key < key)
				{
					cur = cur->_right;
				}
				else if (cur->_key > key)
				{
					cur = cur->_left;
				}
				else
				{
					return false;
				}
			}

				cur = new Node(key);
				if (parent->_key < key)
				{
					parent->_right = cur;
				}
				else
				{
					parent->_left = cur;
				}

				return true;
		}

        查找操作 

        通过搜索二叉树的特性,通过比较大小即可完成查找。

		//查找操作
		bool Find(const K& key)
		{
			Node* cur = _root;
			while (cur)
			{
				if (cur->_key < key)
				{
					cur = cur->_right;
				}
				else if (cur->_key > key)
				{
					cur = cur->_left;
				}
				else
				{
					return true;
				}
			}
			return false;
		}

        删除操作(重点及难点!!!)

         首先查找元素是否在二叉搜索树中,如果不存在,则返回, 否则要删除的结点可能分下面四种情况:

        a. 要删除的结点无孩子结点

        b. 要删除的结点只有左孩子结点

        c. 要删除的结点只有右孩子结点

        d. 要删除的结点有左、右孩子结点

        看起来有待删除节点有4中情况,实际情况a可以与情况b或者c合并起来,因此真正的删除过程如下:

        情况b:删除该结点且使被删除节点的双亲结点指向被删除节点的左孩子结点--直接删除

        情况c:删除该结点且使被删除节点的双亲结点指向被删除结点的右孩子结点--直接删除

        情况d:在它的右子树中寻找中序下的第一个结点(关键码最小),用它的值填补到被删除节点中,再来处理该结点的删除问题--替换法删除

        而在b、c、d这三种情况中,b和c又很相似,所以以大类来划分,我们实际可以分为两种。一种是要删除的节点只有一个左孩子或者右孩子,另一种是有两个孩子节点。

         现在详细介绍这两种情况:

        当只有一个孩子节点时: 当要删节点的左孩子为空时,我们只需要将右半边给他的父亲就行,当然我们也需要注意以下两点:1、如果要删节点是根节点,那么我们需要将它的右孩子的地址覆盖原节点。2、要删节点不是根节点,那么我们也需要判断要删节点是它父节点的左孩子还是右孩子;左孩子则父节点的左孩子节点指向要删孩子的右孩子,右孩子则父节点的右孩子节点指向要删孩子的右孩子。当要删右孩子时也是同理,只是需要注意此时要注意的第二点中要指向的是要删节点是右孩子。下面上半部分的图为此部分的图解~

          当有两个孩子节点时:我们则需要用到替换法。首先,我们需要根据以下规则中的一个规则:1、找到要删节点的左子树的最大节点。2、找到要删奇点的右子树的最小节点。接着,交换要删节点和找到的这个节点。最后,删除找到节点的位置,这个时候,我们就需要返回到上一部分我们只有一个孩子节点时要走的步骤,进行相应的操作为什么呢?因为我们都知道要找最小或者最大只有在最左或者最右。而此时我们一定满足只有一个孩子节点时的于要求。下面下半部分的图为此部分的图解,这里取右子树的最小~

【数据结构】—搜索二叉树(C++实现,超详细!),高阶数据结构炼体 锻体中,数据结构,算法,c++

        实现如下: 

		bool Erase(const K& key)
		{
			Node* parent = nullptr;
			Node* cur = _root;

			while (cur)
			{
				if (cur->_key < key)
				{
					parent = cur;
					cur = cur->_right;
				}
				else if (cur->_key > key)
				{
					parent = cur;
					cur = cur->_left;
				}
				else//表示已经找到,进行删除操作
				{
					//左为空的情况
					if (cur->_left == nullptr)
					{
						if (cur == _root)//要删即为根节点
						{
							_root = cur->_right;
						}
						else
						{
							if (cur == parent->_left)//因为左一定为空,为父节点的左则将右半边给父即可
							{
								parent->_left = cur->_right;
							}
							else//同理为父节点的右则将右半边给父
							{
								parent->_right = cur->_right;
							}
						}

						delete cur;
					}
					else if (cur->_right == nullptr)//右为空的情况
					{
						//同理左为空
						if (cur == _root)
						{
							_root = cur->_left;
						}
						else
						{
							if (cur == parent->_left)
							{
								parent->_left = cur->_left;
							}
							else
							{
								parent->_right = cur->_left;
							}
						}

						delete cur;
					}
					else//左右都不为空
					{//可以选择找该节点左子树的最大节点(最右节点)或者右子树的最小节点(最左节点)
						//这里找右树的最小节点(最左节点)
						Node* parent = cur;
						Node* subleft = cur->_right;
						while (subleft->_left)
						{
							parent = subleft;
							subleft = subleft->_left;
						}

						swap(cur->_key, subleft->_key);
						//由于找到的是最左,则默认左为空,所以只需将右链接给父节点
						if (subleft == parent->_left)
						{
							parent->_left = subleft->_right;
						}
						else
						{
							parent->_right = subleft->_right;
						}

						delete subleft;

					}

					return true;


				}
			}
			return false;
		}

        

递归法操作 

        中序遍历排升序(经典操作!) 

        上面详细介绍过了,不多阐述~

		void _InOrder(Node* root)
		{
			if (root == nullptr)
				return;

			_InOrder(root->_left);
			cout << root->_key << " ";
			_InOrder(root->_right);
		}

         插入操作(递归)

        实际上同非递归的原理是相同的,不多阐述。实在不行画递归展开图就理解了~

		bool _InsertR(Node*& root, const K& key)
		{
			if (root == nullptr)
			{
				root = new Node(key);
				return true;
			}

			if (root->_key < key)
				return _InsertR(root->_right, key);
			else if (root->_key > key)
				return _InsertR(root->_left, key);
			else
				return false;
		}

         查找操作(递归)

		bool _FindR(Node* root, const K& key)
		{
			if (root == nullptr)
			{
				return false;
			}

			if (root->_key < key)
			{
				return _FindR(root->_right, key);
			}
			else if (root->_key > key)
			{
				return _FindR(root->_left, key);
			}
			else
			{
				return true;
			}
		}

        删除操作(递归) 

        实际上操作同非递归是一致的 ,特别注意接口的对于root的引用,这对于后续删除很有作用。当要删除只有一个孩子节点的节点时,同非递归的思想是一样的。当要删节点有两个孩子节点时,在最后面采取的是装换成在子树中去删除,同非递归中的找到替换节点转到只有一个孩子的操作是一样的思想。

		bool _EraseR(Node*& root, const K& key)
		{
			if (root == nullptr)
				return false;

			if (root->_key < key)
			{
				return _EraseR(root->_right, key);
			}
			else if (root->_key > key)
			{
				return _EraseR(root->_left, key);
			}
			else//找到了开始删除
			{
				//实际上的操作同非递归差不多,这里巧妙的对root运用了引用
				if (root->_left == nullptr)
				{
					Node* del = root;
					root = root->_right;
					delete del;
					
					return true;
				}
				else if (root->_right == nullptr)
				{
					Node* del = root;
					root = root->_left;
					delete del;

					return true;
				}
				else//找右子树的最大
				{
					Node* subleft = root->_right;
					while (subleft->_left)
					{
						subleft = subleft->_left;

					}
					swap(root->_key, subleft->_key);

					// 转换成在子树去递归删除
					return _EraseR(root->_right, key);
				}
			}
		}

 二叉搜索树的应用

        以上我们实现的二叉搜索树实际上也被称为K模型,而实际上还有一种模型叫做KV模型,以下为详细介绍:
         1. K模型:K模型即只有key作为关键码,结构中只需要存储Key即可,关键码即为需要搜索到的值。比如:

        给一个单词word,判断该单词是否拼写正确,具体方式如下:

        以词库中所有单词集合中的每个单词作为key,构建一棵二叉搜索树

        在二叉搜索树中检索该单词是否存在,存在则拼写正确,不存在则拼写错误。

        2. KV模型:每一个关键码key,都有与之对应的值Value,即<Key, Value>的键值对。该种方式在现实生活中非常常见:比如

        英汉词典就是英文与中文的对应关系,通过英文可以快速找到与其对应的中文,英文单词与其对应的中文<word, chinese>就构成一种键值对;

        再比如统计单词次数,统计成功后,给定单词就可快速找到其出现的次数,单词与其出现次数就是<word, count>就构成一种键值对

        KV模型二叉搜索树

        KV模型实际上同K模型差不多, 只是在K模型的基础上加了一个value值,对于其它的操作都是相似的,以下给出KV模型的整体代码:

namespace kv
{
	template<class K, class V>
	struct BSTreeNode
	{
		BSTreeNode<K, V>* _left;
		BSTreeNode<K, V>* _right;
		K _key;
		V _value;

		BSTreeNode(const K& key, const V& value)
			:_left(nullptr)
			, _right(nullptr)
			, _key(key)
			, _value(value)
		{}
	};

	template<class K, class V>
	class BSTree
	{
		typedef BSTreeNode<K, V> Node;
	public:
		bool Insert(const K& key, const V& value)
		{
			if (_root == nullptr)
			{
				_root = new Node(key, value);
				return true;
			}

			Node* parent = nullptr;
			Node* cur = _root;
			while (cur)
			{
				parent = cur;

				if (cur->_key < key)
				{
					cur = cur->_right;
				}
				else if (cur->_key > key)
				{
					cur = cur->_left;
				}
				else
				{
					return false;
				}
			}

			cur = new Node(key, value);
			if (parent->_key < key)
			{
				parent->_right = cur;
			}
			else
			{
				parent->_left = cur;
			}

			return true;
		}

		Node* Find(const K& key)
		{
			Node* cur = _root;
			while (cur)
			{
				if (cur->_key < key)
				{
					cur = cur->_right;
				}
				else if (cur->_key > key)
				{
					cur = cur->_left;
				}
				else
				{
					return cur;
				}
			}

			return nullptr;
		}

		bool Erase(const K& key)
		{
			Node* parent = nullptr;
			Node* cur = _root;
			while (cur)
			{
				if (cur->_key < key)
				{
					parent = cur;
					cur = cur->_right;
				}
				else if (cur->_key > key)
				{
					parent = cur;
					cur = cur->_left;
				}
				else
				{
					// 准备删除  20:15继续
					if (cur->_left == nullptr)
					{//左为空
						if (cur == _root)
						{
							_root = cur->_right;
						}
						else
						{
							if (cur == parent->_left)
							{
								parent->_left = cur->_right;
							}
							else
							{
								parent->_right = cur->_right;
							}
						}
					}
					else if (cur->_right == nullptr)
					{//右为空
						if (cur == _root)
						{
							_root = cur->_left;
						}
						else
						{
							if (cur == parent->_left)
							{
								parent->_left = cur->_left;
							}
							else
							{
								parent->_right = cur->_left;
							}
						}
					}
					else
					{//左右都不为空

						// 右树的最小节点(最左节点)
						Node* parent = cur;
						Node* subLeft = cur->_right;
						while (subLeft->_left)
						{
							parent = subLeft;
							subLeft = subLeft->_left;
						}

						swap(cur->_key, subLeft->_key);

						if (subLeft == parent->_left)
							parent->_left = subLeft->_right;
						else
							parent->_right = subLeft->_right;
					}

					return true;
				}
			}

			return false;
		}

		void InOrder()
		{
			_InOrder(_root);
			cout << endl;
		}

	private:
		void _InOrder(Node* root)
		{
			if (root == nullptr)
				return;

			_InOrder(root->_left);
			cout << root->_key << ":" << root->_value << endl;
			_InOrder(root->_right);
		}
	private:
		Node* _root = nullptr;
	};

}

三、整体代码 

#pragma once
#include<iostream>
using namespace std;

namespace K
{
	//节点定义
	template<class K>
	struct BSTreeNode
	{
		BSTreeNode<K>* _left;
		BSTreeNode<K>* _right;
		K _key;

		BSTreeNode(const K& key)
			:_left(nullptr)
			, _right(nullptr)
			, _key(key)
		{}
	};

	//二叉搜索树
	template<class K>
	class BSTree
	{
		typedef BSTreeNode<K> Node;
	public:
		//插入操作,按照左小右大的规则
		bool Insert(const K& key)
		{
			if (_root == nullptr)
			{
				_root = new Node(key);
				return true;
			}

			Node* parent = nullptr;
			Node* cur = _root;
			while (cur)
			{
				parent = cur;
				if (cur->_key < key)
				{
					cur = cur->_right;
				}
				else if (cur->_key > key)
				{
					cur = cur->_left;
				}
				else
				{
					return false;
				}
			}

				cur = new Node(key);
				if (parent->_key < key)
				{
					parent->_right = cur;
				}
				else
				{
					parent->_left = cur;
				}

				return true;
		}

		//查找操作
		bool Find(const K& key)
		{
			Node* cur = _root;
			while (cur)
			{
				if (cur->_key < key)
				{
					cur = cur->_right;
				}
				else if (cur->_key > key)
				{
					cur = cur->_left;
				}
				else
				{
					return true;
				}
			}
			return false;
		}

		bool Erase(const K& key)
		{
			Node* parent = nullptr;
			Node* cur = _root;

			while (cur)
			{
				if (cur->_key < key)
				{
					parent = cur;
					cur = cur->_right;
				}
				else if (cur->_key > key)
				{
					parent = cur;
					cur = cur->_left;
				}
				else//表示已经找到,进行删除操作
				{
					//左为空的情况
					if (cur->_left == nullptr)
					{
						if (cur == _root)//要删即为根节点
						{
							_root = cur->_right;
						}
						else
						{
							if (cur == parent->_left)//因为左一定为空,为父节点的左子树则将右半边给父即可
							{
								parent->_left = cur->_right;
							}
							else//同理为父节点的右则将右半边给父
							{
								parent->_right = cur->_right;
							}
						}

						delete cur;
					}
					else if (cur->_right == nullptr)//右为空的情况
					{
						//同理左为空
						if (cur == _root)
						{
							_root = cur->_left;
						}
						else
						{
							if (cur == parent->_left)
							{
								parent->_left = cur->_left;
							}
							else
							{
								parent->_right = cur->_left;
							}
						}

						delete cur;
					}
					else//左右都不为空
					{//可以选择找该节点左子树的最大节点(最右节点)或者右子树的最小节点(最左节点)
						//这里找右树的最小节点(最左节点)
						Node* parent = cur;
						Node* subleft = cur->_right;
						while (subleft->_left)
						{
							parent = subleft;
							subleft = subleft->_left;
						}

						swap(cur->_key, subleft->_key);
						//由于找到的是最左,则默认左为空,所以只需将右链接给父节点
						if (subleft == parent->_left)
						{
							parent->_left = subleft->_right;
						}
						else
						{
							parent->_right = subleft->_right;
						}

						delete subleft;

					}

					return true;


				}
			}
			return false;
		}

		void InOrder()//中序遍历即排升序
		{
			_InOrder(_root);
			cout << endl;
		}

		bool FindR(const K& key)//递归找
		{
			return _FindR(_root, key);
		}

		bool InsertR(const K& key)//递归插入
		{
			return _InsertR(_root, key);
		}

		bool EraseR(const K& key)//递归删
		{
			return _EraseR(_root, key);
		}

		BSTree() = default;// C++11

		~BSTree()
		{
			Destroy(_root);
		}

		BSTree(const BSTree<K>& t)
		{
			_root = Copy(t._root);
		}

		// t1 = t3
		BSTree<K>& operator=(BSTree<K> t)
		{
			swap(_root, t._root);
			return *this;
		}

	private:

		Node* Copy(Node* root)
		{
			if (root == nullptr)
				return nullptr;

			Node* newRoot = new Node(root->_key);
			newRoot->_left = Copy(root->_left);
			newRoot->_right = Copy(root->_right);

			return newRoot;
		}

		void Destroy(Node*& root)
		{
			if (root == nullptr)
				return;

			Destroy(root->_left);
			Destroy(root->_right);
			delete root;
			root = nullptr;
		}

		bool _EraseR(Node*& root, const K& key)
		{
			if (root == nullptr)
				return false;

			if (root->_key < key)
			{
				return _EraseR(root->_right, key);
			}
			else if (root->_key > key)
			{
				return _EraseR(root->_left, key);
			}
			else//找到了开始删除
			{
				//实际上的操作同非递归差不多,这里巧妙的对root运用了引用
				if (root->_left == nullptr)
				{
					Node* del = root;
					root = root->_right;
					delete del;
					
					return true;
				}
				else if (root->_right == nullptr)
				{
					Node* del = root;
					root = root->_left;
					delete del;

					return true;
				}
				else//找右子树的最大
				{
					Node* subleft = root->_right;
					while (subleft->_left)
					{
						subleft = subleft->_left;

					}
					swap(root->_key, subleft->_key);

					// 转换成在子树去递归删除
					return _EraseR(root->_right, key);
				}
			}
		}

		bool _InsertR(Node*& root, const K& key)
		{
			if (root == nullptr)
			{
				root = new Node(key);
				return true;
			}

			if (root->_key < key)
				return _InsertR(root->_right, key);
			else if (root->_key > key)
				return _InsertR(root->_left, key);
			else
				return false;
		}

		bool _FindR(Node* root, const K& key)
		{
			if (root == nullptr)
			{
				return false;
			}

			if (root->_key < key)
			{
				return _FindR(root->_right, key);
			}
			else if (root->_key > key)
			{
				return _FindR(root->_left, key);
			}
			else
			{
				return true;
			}
		}

		void _InOrder(Node* root)
		{
			if (root == nullptr)
				return;

			_InOrder(root->_left);
			cout << root->_key << " ";
			_InOrder(root->_right);
		}

		Node* _root = nullptr;
	};
}



namespace kv
{
	template<class K, class V>
	struct BSTreeNode
	{
		BSTreeNode<K, V>* _left;
		BSTreeNode<K, V>* _right;
		K _key;
		V _value;

		BSTreeNode(const K& key, const V& value)
			:_left(nullptr)
			, _right(nullptr)
			, _key(key)
			, _value(value)
		{}
	};

	template<class K, class V>
	class BSTree
	{
		typedef BSTreeNode<K, V> Node;
	public:
		bool Insert(const K& key, const V& value)
		{
			if (_root == nullptr)
			{
				_root = new Node(key, value);
				return true;
			}

			Node* parent = nullptr;
			Node* cur = _root;
			while (cur)
			{
				parent = cur;

				if (cur->_key < key)
				{
					cur = cur->_right;
				}
				else if (cur->_key > key)
				{
					cur = cur->_left;
				}
				else
				{
					return false;
				}
			}

			cur = new Node(key, value);
			if (parent->_key < key)
			{
				parent->_right = cur;
			}
			else
			{
				parent->_left = cur;
			}

			return true;
		}

		Node* Find(const K& key)
		{
			Node* cur = _root;
			while (cur)
			{
				if (cur->_key < key)
				{
					cur = cur->_right;
				}
				else if (cur->_key > key)
				{
					cur = cur->_left;
				}
				else
				{
					return cur;
				}
			}

			return nullptr;
		}

		bool Erase(const K& key)
		{
			Node* parent = nullptr;
			Node* cur = _root;
			while (cur)
			{
				if (cur->_key < key)
				{
					parent = cur;
					cur = cur->_right;
				}
				else if (cur->_key > key)
				{
					parent = cur;
					cur = cur->_left;
				}
				else
				{
					// 准备删除  20:15继续
					if (cur->_left == nullptr)
					{//左为空
						if (cur == _root)
						{
							_root = cur->_right;
						}
						else
						{
							if (cur == parent->_left)
							{
								parent->_left = cur->_right;
							}
							else
							{
								parent->_right = cur->_right;
							}
						}
					}
					else if (cur->_right == nullptr)
					{//右为空
						if (cur == _root)
						{
							_root = cur->_left;
						}
						else
						{
							if (cur == parent->_left)
							{
								parent->_left = cur->_left;
							}
							else
							{
								parent->_right = cur->_left;
							}
						}
					}
					else
					{//左右都不为空

						// 右树的最小节点(最左节点)
						Node* parent = cur;
						Node* subLeft = cur->_right;
						while (subLeft->_left)
						{
							parent = subLeft;
							subLeft = subLeft->_left;
						}

						swap(cur->_key, subLeft->_key);

						if (subLeft == parent->_left)
							parent->_left = subLeft->_right;
						else
							parent->_right = subLeft->_right;
					}

					return true;
				}
			}

			return false;
		}

		void InOrder()
		{
			_InOrder(_root);
			cout << endl;
		}

	private:
		void _InOrder(Node* root)
		{
			if (root == nullptr)
				return;

			_InOrder(root->_left);
			cout << root->_key << ":" << root->_value << endl;
			_InOrder(root->_right);
		}
	private:
		Node* _root = nullptr;
	};

}

                        感谢你耐心的看到这里ღ( ´・ᴗ・` )比心,如有哪里有错误请踢一脚作者o(╥﹏╥)o! 

                                       【数据结构】—搜索二叉树(C++实现,超详细!),高阶数据结构炼体 锻体中,数据结构,算法,c++

                                                                         给个三连再走嘛~  文章来源地址https://www.toymoban.com/news/detail-755671.html

到了这里,关于【数据结构】—搜索二叉树(C++实现,超详细!)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 数据结构:搜索二叉树 | 平衡二叉树

    博客写的代码都放在这里:gitee仓库链接 1.二叉搜索树 1.1.基本概念 二叉搜索树又称二叉排序树, 可以为空,如果不为空具有以下性质的二叉树 : 若它的左子树不为空,则左子树上所有节点的值都小于根节点的值 若它的右子树不为空,则右子树上所有节点的值都大于根节点的

    2024年01月23日
    浏览(40)
  • 数据结构——二叉搜索树(附带C++实现版本)

    二叉搜索树又叫二叉排序树 ,二叉搜索树也是一种树形结构。 它是一课满足以下性质的搜索树: 若它的左子树不为空,则左子树上所有节点的值都小于根节点的值 若它的右子树不为空,则右子树上所有节点的值都大于根节点的值 它的左右子树也分别是二叉搜索树 注意,二

    2024年02月12日
    浏览(26)
  • 【数据结构】二叉树遍历的实现(超详细解析,小白必看系列)

    目录 一、前言 🍎为何使用链式二叉树   🍐何为链式二叉树  🍉二叉树的构建 💦创建二叉链结构 💦手动构建一颗树  🍓二叉树的遍历 (重点) 💦前序遍历  💦中序遍历  💦后续遍历  🍌二叉树的经典问题(重点) 💦二叉树节点个数  💦二叉树叶子节点的个数  💦

    2024年02月02日
    浏览(33)
  • C++------利用C++实现二叉搜索树【数据结构】

    什么是二叉搜索树,二叉搜索树就是指左孩子永远比根小右孩子永远比根大。这个规则适用于所有的子树。 上面的就是一棵二叉搜索树,我们还可以发现这棵树走一个中序遍历序列是有序的,所以它又被称为二叉排序树。 二叉搜索树的操作主要分为以下几点,查找, 插入,

    2024年02月11日
    浏览(29)
  • 数据结构与算法—二叉树数组表示(ArrayBinTree)、二叉树的链式表示(LinkedBinTree)的基于C++模板代码实现

    1、二叉树的顺序表示:ArrayBinTree.h 二叉树的顺序表示法操作方便,但缺点是容易造成存储空间浪费。 这是一个用数组实现的二叉树类模板。它可以创建一个空树,也可以在指定的位置插入结点并设置结点的值,可以删除子树,并支持逐层遍历。使用该类时,需要提供一个元

    2024年02月06日
    浏览(27)
  • 数据结构_进阶(1):搜索二叉树

    建议再看这节之前能对C++有一定了解 二叉树在前面C的数据结构阶段时有出过,现在我们对二叉树来学习一些更复杂的类型,也为之后C++学习的 map 和 set 做铺垫 1. map和set特性需要先铺垫二叉搜索树 ,而二叉搜索树也是一种树形结构 2. 二叉搜索树的特性了解,有助于更好的理

    2024年02月16日
    浏览(37)
  • C++数据结构与算法详解:链表、栈、队列、树、二叉树和图结构的实现与应用

    链表是一种常见的数据结构由一系列节点按顺序连接而成,一般每个节点包含一个数据元素和一个指向下一个节点的引用。 链表有多种类型: 单向链表:每个节点只有一个指向下一个节点的引用 双向链表:每个节点有一个指向前一个节点和一个指向后一个节点的引用 循环链

    2024年02月04日
    浏览(31)
  • [数据结构进阶 C++] 二叉搜索树(BinarySearchTree)的模拟实现

    二叉搜索树又称二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树: 若它的左子树不为空,则左子树上所有节点的值都小于根节点的值 若它的右子树不为空,则右子树上所有节点的值都大于根节点的值 它的左右子树也分别为二叉搜索树 我们先给出两个示例: 此

    2024年02月04日
    浏览(27)
  • 数据结构——常见二叉树的分类(完全二叉树、满二叉树、平衡二叉树、二叉搜索树、红黑树)

    专业术语 中文 描述 Root 根节点 一棵树的顶点 Child 孩子结点 一个结点含有的子树的根节点称为该结点的子节点 Leaf 叶子结点 没有孩子的节点 Degree 度 一个节点包含子树的数量 Edge 边 一个节点与另外一个节点的连接 Depth 深度 根节点到这个节点经过边的数量 Height 节点高度 从

    2024年02月03日
    浏览(33)
  • 数据结构第四天: Complete Binary Search Tree 【搜索二叉树,完全二叉树】

     这道题需要的操作时排序并且需要遍历,最重要的一点它是个完全二叉树,所以数组是最适合的 这道题我的思路来自于浙江大学课件7.0.2完全二叉树 这道题说白就是将输入的样例构造成一个完全搜索二叉树。因为完全线索二叉树的 根节点一定是是一个处于左右子树中间的那

    2024年02月06日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包