秒懂C++之二叉搜索树

fe594ea5bf754ddbb223a54d8fb1e7bc.gif

目录

前言

一. 二叉搜索树实现

1.1 二叉搜索树概念

1.2 二叉搜索树的查找

非递归:

递归;

1.3 二叉搜索树的插入

非递归:

递归:

1.4 二叉搜索树的删除

非递归:

递归:

1.5 拷贝构造

1.6 运算符=

1.7 析构函数

二.KV模型二叉树

三.全部代码


前言

学习二叉搜索树是为了后面的map与set作铺垫有助于更好理解其特性~

一. 二叉搜索树实现

1.1 二叉搜索树概念

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

通俗来讲就是中序遍历是排好序的~

接下来我们就以该图进行二叉树的实现原理~ 

1.2 二叉搜索树的查找

二叉树的查找很简单,我们只需要利用二叉搜索树的特性即可:

我们要找的值比8小,则去左子树找(因为左子树都是比8小的)。比3大则去右子树找,比6大继续去右子树找。直到找到或为空为止~

非递归:

template<class K>
struct BSTreeNode
{
	typedef BSTreeNode<K> Node;

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

};

template<class K>
class BSTree
{
	typedef BSTreeNode<K> Node;
public:
	//二叉树查找
	bool Find(const K& key)
	{
		Node* cur = _root;
		
		while (cur)
		{
			if (key > cur->_key)
			{
				cur = cur->_right;
			}
			else if (key < cur->_key)
			{
				cur = cur->_left;
			}
			else
			{
				return true;
			}
		}
		return false;
	}

private:
	Node* _root = nullptr;
};

递归;

bool FindR(const K& key)
	{
		return  _FindR(_root, key);
	}
	//寻找递归版本
	bool _FindR(Node* root, const K& key)
	{
		if (root == nullptr)
		{
			return false;
		}
		if (key > root->_key)
		{
			return _FindR(root->_right, key);
		}
		else if (key < root->_key)
		{
			return _FindR(root->_left, key);
		}
		else
		{
			return true;
		}

	}

1.3 二叉搜索树的插入

插入我们只需要继续查找的套路就行了,只不过在最后是为空节点的时候插入~

非递归:

template<class K>
struct BSTreeNode
{
	typedef BSTreeNode<K> Node;

	Node* _left;
	Node* _right;
	K _key;

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

};

template<class K>
class BSTree
{
	typedef BSTreeNode<K> Node;
public:
	//二叉树查找
	bool Find(const K& key)
	{
		Node* cur = _root;
		
		while (cur)
		{
			if (key > cur->_key)
			{
				cur = cur->_right;
			}
			else if (key < cur->_key)
			{
				cur = cur->_left;
			}
			else
			{
				return true;
			}
		}
		return false;
	}

	//二叉树插入
	bool Insert(const K& key)
	{

		if (_root == nullptr)
		{
			_root = new Node(key);
			return true;
		}
		Node* cur = _root;
		Node* parent = nullptr;
		while (cur)
		{
			if (key > cur->_key)
			{
				parent = cur;
				cur = cur->_right;
			}
			else if (key < cur->_key)
			{
				parent = cur;
				cur = cur->_left;
			}
			else
			{
				return false;
			}
		}
		//cur指向空节点时开始插入
		cur = new Node(key);
		//如果父节点的左节点存在则插入其右节点
		if (key>parent->_key)
		{
			parent->_right = cur;
		}
		if (key < parent->_key)
		{
			parent->_left = cur;
		}
		return true;
	}
	//中序遍历
	void Inorder()
	{
		_Inorder(_root);
		cout << endl;
	}


	void _Inorder(Node* root)
	{
		if (root == nullptr)
		{
			return;
		}
		_Inorder(root->_left);
		cout << root->_key << " ";
		_Inorder(root->_right);
	}

private:
	Node* _root = nullptr;
};

ps:插入有几点细节需要注意

  • 开始如果是空树需要特殊判断
  • 最后cur找到空节点后还需要与父节点链接起来,所以记得记录cur的父节点
  • 我们编写中序遍历时在类外是取不到_root的,所以需要套一层外壳~递归都需要套一层壳~

递归:

bool InsertR(const K& key)
	{
		return  _InsertR(_root, key);
	}

	//插入递归版本
	bool _InsertR(Node*& root, const K& key)
	{
		if (root == nullptr)
		{
			root = new Node(key);
			return true;
		}
		if (key > root->_key)
		{
			return _InsertR(root->_right, key);
		}
		else if (key < root->_key)
		{
			return _InsertR(root->_left, key);
		}
		else
		{
			return false;
		}

	}

ps:不用去担心插入后的节点链接问题~引用帮我们解决了一切,这也是引用在递归中很精妙的写法~

 

1.4 二叉搜索树的删除

非递归:

删除的情况很复杂,我们先对删除划分情况

  • 要删除的结点无孩子结点或只有一个孩子节点
  • 要删除的结点有左、右孩子结点

我们先来重点讨论第一种划分:

除了考虑寻常节点外,我们还得考虑删除根节点的情况~

最后再来讨论第二种划分:

这里解释一下,因为rightmin已经是最左节点,那么其左孩子一定是空节点,只要跟着这个线索就可以找到rightmin节点了~本质其实就是找到可以替换的节点,然后数据交换,最后删除节点~

至此所有情况全都说明完毕,其实只是在两种划分考虑正常节点的基础上再考虑根节点的情况而言

bool Erase(const K& key)
	{
		if (_root == nullptr)
		{
			return false;
		}
		Node* parent = nullptr;
		Node* cur = _root;
		while (cur)
		{
			if (key > cur->_key)
			{
				parent = cur;
				cur = cur->_right;
			}
			else if (key < cur->_key)
			{
				parent = cur;
				cur = cur->_left;
			}
			//找到目标节点
			else
			{
				//开始划分情况
				//目标节点没有左节点,有右节点
				if (cur->_left == nullptr)
				{	//如果删除的是根节点
					if (cur == _root)
					{
						cur = _root->_right;
					}
					//正常节点
					else
					{
						//看删除节点是父节点的左还是右
						if (cur == parent->_right)
						{
							//让父节点链接删除节点的右节点
							parent->_right = cur->_right;
						}
						else
						{
							parent->_left = cur->_right;
						}
					}
					delete cur;
					return true;
				}
				//目标节点有左节点,没有右节点
				else if (cur->_right == nullptr)
				{
					//如果删除的是根节点
					if (cur == _root)
					{
						_root = _root->_left;
					}
					//正常节点
					else
					{
						//看删除节点是父节点的左还是右
						if (cur == parent->_right)
						{
							//让父节点链接删除节点的左节点
							parent->_right = cur->_left;
						}
						else
						{
							parent->_left = cur->_left;
						}
					}
					delete cur;
					return true;
				}
				//如果目标节点有两个孩子节点
				//替换法
				else
				{
					Node* rightminparent = cur;
					Node* rightmin = cur->_right;
					while (rightmin->_left)
					{
						rightminparent = rightmin;
						rightmin = rightmin->_left;
					}
					cur->_key = rightmin->_key;
					if (rightmin == rightminparent->_left)
					{
						rightminparent->_left = rightmin->_right;
					}
					else
					{
						rightminparent->_right = rightmin->_right;
					}
					delete rightmin;
					return true;
				}
				
			}
		}
		return false;

	}

 

递归:

	//删除递归版本
	bool EraseR(const K& key)
	{
		return _EraseR(_root,key);
	}
	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
		{
			Node* del = root;
			if (root->_right == nullptr)
			{
				root = root->_left;
			}
			else if (root->_left == nullptr)
			{
				root = root->_right;
			}
			else
			{
				Node* rightMin = root->_right;
				while (rightMin->_left)
				{
					rightMin = rightMin->_left;
				}

				swap(root->_key, rightMin->_key);

				return _EraseR(root->_right, key);
			}

			delete del;
			return true;
		}
	}

这里同样用引用解决了删除节点后剩下的链接问题~

1.5 拷贝构造

// 写了拷贝构造就不会有默认构造了 强制生成默认构造
	BSTree() = default;

//拷贝构造
	BSTree(const BSTree<K>& t)
	{
		_root = Copy(t._root);
	}

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;
	}

 

1.6 运算符=

//赋值 现代写法
	BSTree<K>& operator=(BSTree<K> t)
	{
		swap(_root, t._root);
		return *this;
	}

1.7 析构函数

 

~BSTree()
	{
		Destroy(_root);
	}

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

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

析构函数正常用后续遍历删除节点即可~ 

二.KV模型二叉树

我们上述实现的就是K模型二叉树,而kv模型二叉树就是多传了一个value值而已~

拿商场停车场作类比~

  • 进入商场停车场(记录k值车牌号,记录v值停车时间)
  • 离开商场停车场(查看k值车牌号,查看v值停车时间,根据时间收费)

这里我们用kv模型来实现英汉词典

英汉词典就是英文与中文的对应关系,通过英文可以快速找到与其对应的中文,英
文单词与其对应的中文就构成一种键值对;
namespace key_value
{
	template<class K, class V>
	struct BSTreeNode
	{
		typedef BSTreeNode<K, V> Node;

		Node* _left;
		Node* _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)
			{
				if (cur->_key < key)
				{
					parent = cur;
					cur = cur->_right;
				}
				else if (cur->_key > key)
				{
					parent = cur;
					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
				{
					if (cur->_left == nullptr)
					{
						if (cur == _root)
						{
							_root = cur->_right;
						}
						else
						{
							if (cur == parent->_right)
							{
								parent->_right = cur->_right;
							}
							else
							{
								parent->_left = cur->_right;
							}
						}

						delete cur;
						return true;
					}
					else if (cur->_right == nullptr)
					{
						if (cur == _root)
						{
							_root = cur->_left;
						}
						else
						{
							if (cur == parent->_right)
							{
								parent->_right = cur->_left;
							}
							else
							{
								parent->_left = cur->_left;
							}
						}

						delete cur;
						return true;
					}
					else
					{
						// 替换法
						Node* rightMinParent = cur;
						Node* rightMin = cur->_right;
						while (rightMin->_left)
						{
							rightMinParent = rightMin;
							rightMin = rightMin->_left;
						}

						cur->_key = rightMin->_key;

						if (rightMin == rightMinParent->_left)
							rightMinParent->_left = rightMin->_right;
						else
							rightMinParent->_right = rightMin->_right;

						delete rightMin;
						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 << " ";
			_InOrder(root->_right);
		}

	private:
		Node* _root = nullptr;
	};
}

其实kv模型也就是在插入的时候添加了value值而已,然后我们通过查找key值可以映射对应的value值。

三.全部代码

//BinarySearchTree.h
#pragma once

template<class K>
struct BSTreeNode
{
	typedef BSTreeNode<K> Node;

	Node* _left;
	Node* _right;
	K _key;

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

};

template<class K>
class BSTree
{
	typedef BSTreeNode<K> Node;
public:
	// 写了拷贝构造就不会有默认构造了 强制生成默认构造
	BSTree() = default;
	//拷贝构造
	BSTree(const BSTree<K>& t)
	{
		_root = Copy(t._root);
	}

	//赋值 现代写法
	BSTree<K>& operator=(BSTree<K> t)
	{
		swap(_root, t._root);
		return *this;
	}

	~BSTree()
	{
		Destroy(_root);
	}

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

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

	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;
	}

	bool FindR(const K& key)
	{
		return _FindR(_root, key);
	}
	//寻找递归版本
	bool _FindR(Node* root, const K& key)
	{
		if (root == nullptr)
		{
			return false;
		}
		if (key > root->_key)
		{
			return _FindR(root->_right, key);
		}
		else if (key < root->_key)
		{
			return _FindR(root->_left, key);
		}
		else
		{
			return true;
		}

	}


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

	bool InsertR(const K& key)
	{
		return _InsertR(_root, key);
	}

	//插入递归版本
	bool _InsertR(Node*& root, const K& key)
	{
		if (root == nullptr)
		{
			root = new Node(key);
			return true;
		}
		if (key > root->_key)
		{
			return _InsertR(root->_right, key);
		}
		else if (key < root->_key)
		{
			return _InsertR(root->_left, key);
		}
		else
		{
			return false;
		}

	}

	  
	//二叉树插入
	//bool Insert(const K& key)
	//{

	//	if (_root == nullptr)
	//	{
	//		_root = new Node(key);
	//		return true;
	//	}
	//	Node* cur = _root;
	//	Node* parent = nullptr;
	//	while (cur)
	//	{
	//		if (key > cur->_key)
	//		{
	//			parent = cur;
	//			cur = cur->_right;
	//		}
	//		else if (key < cur->_key)
	//		{
	//			parent = cur;
	//			cur = cur->_left;
	//		}
	//		else
	//		{
	//			return false;
	//		}
	//	}
	//	//cur指向空节点时开始插入
	//	cur = new Node(key);
	//	//如果父节点的左节点存在则插入其右节点
	//	if (key>parent->_key)
	//	{
	//		parent->_right = cur;
	//	}
	//	if (key < parent->_key)
	//	{
	//		parent->_left = cur;
	//	}
	//	return true;
	//}
	//中序遍历
	void Inorder()
	{
		_Inorder(_root);
		cout << endl;
	}

	//中序遍历
	void _Inorder(Node* root)
	{
		if (root == nullptr)
		{
			return;
		}
		_Inorder(root->_left);
		cout << root->_key << " ";
		_Inorder(root->_right);
	}
	//删除递归版本
	bool EraseR(const K& key)
	{
		return _EraseR(_root,key);
	}
	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
		{
			Node* del = root;
			if (root->_right == nullptr)
			{
				root = root->_left;
			}
			else if (root->_left == nullptr)
			{
				root = root->_right;
			}
			else
			{
				Node* rightMin = root->_right;
				while (rightMin->_left)
				{
					rightMin = rightMin->_left;
				}

				swap(root->_key, rightMin->_key);

				return _EraseR(root->_right, key);
			}

			delete del;
			return true;
		}
	}
	
	//bool Erase(const K& key)
	//{
	//	if (_root == nullptr)
	//	{
	//		return false;
	//	}
	//	Node* parent = nullptr;
	//	Node* cur = _root;
	//	while (cur)
	//	{
	//		if (key > cur->_key)
	//		{
	//			parent = cur;
	//			cur = cur->_right;
	//		}
	//		else if (key < cur->_key)
	//		{
	//			parent = cur;
	//			cur = cur->_left;
	//		}
	//		//找到目标节点
	//		else
	//		{
	//			//开始划分情况
	//			//目标节点没有左节点,有右节点
	//			if (cur->_left == nullptr)
	//			{	//如果删除的是根节点
	//				if (cur == _root)
	//				{
	//					cur = _root->_right;
	//				}
	//				//正常节点
	//				else
	//				{
	//					//看删除节点是父节点的左还是右
	//					if (cur == parent->_right)
	//					{
	//						//让父节点链接删除节点的右节点
	//						parent->_right = cur->_right;
	//					}
	//					else
	//					{
	//						parent->_left = cur->_right;
	//					}
	//				}
	//				delete cur;
	//				return true;
	//			}
	//			//目标节点有左节点,没有右节点
	//			else if (cur->_right == nullptr)
	//			{
	//				//如果删除的是根节点
	//				if (cur == _root)
	//				{
	//					_root = _root->_left;
	//				}
	//				//正常节点
	//				else
	//				{
	//					//看删除节点是父节点的左还是右
	//					if (cur == parent->_right)
	//					{
	//						//让父节点链接删除节点的左节点
	//						parent->_right = cur->_left;
	//					}
	//					else
	//					{
	//						parent->_left = cur->_left;
	//					}
	//				}
	//				delete cur;
	//				return true;
	//			}
	//			//如果目标节点有两个孩子节点
	//			//替换法
	//			else
	//			{
	//				Node* rightminparent = cur;
	//				Node* rightmin = cur->_right;
	//				while (rightmin->_left)
	//				{
	//					rightminparent = rightmin;
	//					rightmin = rightmin->_left;
	//				}
	//				cur->_key = rightmin->_key;
	//				if (rightmin == rightminparent->_left)
	//				{
	//					rightminparent->_left = rightmin->_right;
	//				}
	//				else
	//				{
	//					rightminparent->_right = rightmin->_right;
	//				}
	//				delete rightmin;
	//				return true;
	//			}
	//			
	//		}
	//	}
	//	return false;

	//}

private:
	Node* _root = nullptr;
};




namespace key_value
{
	template<class K, class V>
	struct BSTreeNode
	{
		typedef BSTreeNode<K, V> Node;

		Node* _left;
		Node* _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)
			{
				if (cur->_key < key)
				{
					parent = cur;
					cur = cur->_right;
				}
				else if (cur->_key > key)
				{
					parent = cur;
					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
				{
					if (cur->_left == nullptr)
					{
						if (cur == _root)
						{
							_root = cur->_right;
						}
						else
						{
							if (cur == parent->_right)
							{
								parent->_right = cur->_right;
							}
							else
							{
								parent->_left = cur->_right;
							}
						}

						delete cur;
						return true;
					}
					else if (cur->_right == nullptr)
					{
						if (cur == _root)
						{
							_root = cur->_left;
						}
						else
						{
							if (cur == parent->_right)
							{
								parent->_right = cur->_left;
							}
							else
							{
								parent->_left = cur->_left;
							}
						}

						delete cur;
						return true;
					}
					else
					{
						// 替换法
						Node* rightMinParent = cur;
						Node* rightMin = cur->_right;
						while (rightMin->_left)
						{
							rightMinParent = rightMin;
							rightMin = rightMin->_left;
						}

						cur->_key = rightMin->_key;

						if (rightMin == rightMinParent->_left)
							rightMinParent->_left = rightMin->_right;
						else
							rightMinParent->_right = rightMin->_right;

						delete rightMin;
						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 << " ";
			_InOrder(root->_right);
		}

	private:
		Node* _root = nullptr;
	};
}
//test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>

using namespace std;

#include "BinarySearchTree.h"


//int main()
//{
//	/*BSTree<int> t;
//	int a[] = { 8, 3, 1, 10, 6, 4, 7, 14, 13 };
//	
//	for (auto e : a)
//	{
//		t.InsertR(e);
//	}
//	t.Inorder();
//
//
//	BSTree<int> t1;
//	t1 = t;
//	t1.Inorder();
//	t1.Inorder();*/
//
//	/*BSTree<int> t1(t);
//	t1.Inorder();*/
//	/*for (auto e : a)
//	{
//		t.EraseR(e);
//		t.Inorder();
//	}*/
//
//	//BSTree<int> t;
//
//	/*t.Inorder();
//	BSTree<int> t;
//
//
//	cout << t.Find(8) << endl;
//	cout << t.Find(14) << endl;
//	cout << t.Find(15) << endl;*/
//
//
//	key_value::BSTree<string,string> t;
//
//
//
//
//	return 0;
//
//}

int main()
{
	key_value::BSTree<string, string> dict;
	dict.Insert("apple", "苹果");
	dict.Insert("keep", "坚持");
	dict.Insert("good", "好棒");
	dict.Insert("sleep", "睡觉");

	string str;
	while (cin >> str)
	{
		auto ret = dict.Find(str);
		if (ret)
		{
			cout << ret->_value << endl;
		}
		else
		{
			cout << "找不到" << endl;
		}
	}

	return 0;
}

  • 10
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C++ STL中没有直接提供二叉搜索树的实现,但STL中有一些关于树的容器,比如set和map,它们底层的实现就是基于红黑树(一种平衡二叉搜索树)的。你可以使用这些容器来实现二叉搜索树的功能。关于二叉搜索树的一些知识,比如二叉树的遍历、迭代、线索二叉树、堆、Huffman编码、AVL树等都可以在STL中找到相应的实现。 二叉搜索树的查找可以通过比较根节点的值和目标值的大小来判断是往左子树还是往右子树查找,并重复这个过程直到找到目标值或者遍历到叶子节点为止。常规实现使用循环来实现查找,递归实现使用递归函数来查找。 二叉搜索树的插入操作也可以通过递归或循环来实现,根据目标值和当前节点的值的大小关系来决定是往左子树还是往右子树插入新节点。 STL中的二叉搜索树容器如set和map提供了插入、删除和查找等功能,并且保持了二叉搜索树的性质。你可以使用这些容器来处理二叉搜索树相关的操作。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [C++ STL 数据结构 树](https://download.csdn.net/download/xinxipan/3008948)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [【C++ STL】-- 二叉搜索树](https://blog.csdn.net/weixin_64609308/article/details/128018280)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值