二叉搜索树的模拟实现

1.二叉搜索树概念

概念:二叉搜索树又称二叉排序树,它是一颗空树或者是一颗具有以下特征的二叉树:
1.若它的左子树不为空,则它的左子树上所有的结点值都小于根节点的值。
2.若它的右子树不为空,则它的柚子树上所有的结点值都大于根节点的值。
3.它的左右子树也为二叉搜索树。
也就是如果是中序遍历的话,结果为有小到大的有序排列

2.二叉搜索树的实现

二叉搜索树的几个基本功能:
1.插入
2.删除
3.查找
4.中序遍历

2.1二叉搜索树需要的节点

template<class K>
struct BSTreeNode
{
	BSTreeNode<K>* _left;
	BSTreeNode<K>* _right;
	K _key;

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

2.2插入的实现

这里我们准备了两个版本的插入实现:
非递归版的实现:

 bool Insert(const K& key)//非递归版
	{
		if (_root == nullptr)
		{
			_root = new Node(key);
			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);
		if (parent->_key < key)
		{
			parent->_right = cur;
		}
		else
		{
			parent->_left = cur;
		}

			return true;
	}

递归版的实现:

 	bool Insert(const K & key)
		{
			return _Insert(_root, key);
		}
    bool _Insert(Node*& root, const K& key)
		{
			if (root == nullptr)
			{
				//这里是否有疑问为啥可以直接new一个新,不考虑链接吗
				//原因在参数Node *& root,这里我们有一个引用,每次传递来的是对其区别名
				root = new Node(key); 
				return true;
			}
			if (root->_key < key)
			{
				return _Insert(root->_right, key);
			}
			else if (root->_key > key)
			{
				return _Insert(root->_left, key);
			}
			else
			{
				return false;
			}
		}

2.3删除

这里也是提供两个版本的实现方式:
1.非递归的方式

 bool Erase(const K & key)
		{
			Node* cur = _root;
			Node* parent = nullptr;
			while (cur)
			{
				//先找到要插入的地方
				if (cur->_key > key)
			{
					parent = cur;
					cur = cur->_left;
				}
				else if (cur->_key < key)
			{
					parent = cur;
					cur = cur->_right;
				}
				else//找到了
		     	{
					//左右有一个为空,左为空
					if (cur->_left == nullptr)
					{
						if (cur == _root)//cur为根时
						{
							_root = _root->_right;
						}
						else//不为空时,判断此时cur为parent的左还是右
						{
							if (parent->_left == cur)
							{
								parent->_left = cur->_right;
							}
							else
							{
								parent->_right = cur->_right;
							}
						}
					}
					//左右有一个为空,右为空
					else if (cur->_right == nullptr)
					{
						if (cur == _root)//cur为根时
						{
							_root = _root->_left;
						}
						else//不为空时,判断此时cur为parent的左还是右
						{
							if (parent->_left == cur)
							{
								parent->_left = cur->_left;
							}
							else
							{
								parent->_right = cur->_left;
							}
						}
					}
				    else  //cur的左右两边都不为空时
					{
						//leftMax为替代节点
						Node* leftMax = cur->_left;
						parent = cur;//这里不能给空,如果leftMax直接找到,parent就无法找到了
						while (leftMax->_right)//找到cur左边最大的那一个
						{
						    parent = leftMax;
							leftMax = leftMax->_right;
						}
						//找到后交换
						swap(cur->_key, leftMax->_key);
						//不要忽略链接的问题,也就是为啥要给parent  cur的原因置空可能找不到parent
						if (parent->_left == leftMax)
						{
							parent->_left = leftMax->_left;
						}
						else
						{
							parent->_right = leftMax->_left;
						}
						cur = leftMax;
					}
					delete cur;
					return true;
				}

			}
			return false;
		}

2.递归版本:

 bool Erase(const K& key)
		{
			return _Erase(_root, key);
		}
 bool _Erase(Node*& root,const K& key)
	    {
			if (root == nullptr)
			{
				return false;
			}
			if (root->_key < key)
			{
				return _Erase(root->_right, key);
			}
			else if (root->_key > key)
			{
				return _Erase(root->_left, key);

			}
			else//找到了
			{
				Node* del = root;
				// 1、左为空
				if (root->_left == nullptr)
				{
					root = root->_right;
				}
				// 2、右为空
				else if (root->_right == nullptr)
				{
					root = root->_left;
				}
				// 3、左右都不为空
				else
				{
					 
					//找到右边最大进行交换
					Node* LeftMax = root->_left;
					while (LeftMax->_right)
					{
						LeftMax = LeftMax->_right;
					}

					swap(root->_key, LeftMax->_key);
					return _Erase(root->_left, key);//不能传leftmax,为局部变量

				}
				delete del;
				return true;
			}
		}

2.4查找

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

2.5中序遍历

 void InOrder()
		{
			_InOrder(_root);
			cout << endl;
		}
void _InOrder(Node * root)
	  {
			if (root == NULL)
			{
				return;
			}
			_InOrder(root->_left);
			cout << root->_key << " ";
			_InOrder(root->_right);
	 }

最后我们来看:

#pragma once

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:
	BSTree()
		:_root(nullptr)
	{}
	BSTree(const BSTree<K>& t)
	{
		_root = copy(t._root);
	}
	~BSTree()
	{
		Destroy(_root); 
	}
	BSTree<K>& operator=(BSTree<K> t)
	{

		swap(_root, t._root);
		return *this;
	}
	/*bool Insert(const K& key)//非递归版
	{
		if (_root == nullptr)
		{
			_root = new Node(key);
			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);
		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* cur = _root;
		//	Node* parent = nullptr;
		//	while (cur)
		//	{
		//		//先找到要插入的地方
		//		if (cur->_key > key)
		//		{
		//			parent = cur;
		//			cur = cur->_left;
		//		}
		//		else if (cur->_key < key)
		//		{
		//			parent = cur;
		//			cur = cur->_right;
		//		}
		//		else//找到了
		//		{
		//			//左右有一个为空,左为空
		//			if (cur->_left == nullptr)
		//			{
		//				if (cur == _root)//cur为根时
		//				{
		//					_root = _root->_right;
		//				}
		//				else//不为空时,判断此时cur为parent的左还是右
		//				{
		//					if (parent->_left == cur)
		//					{
		//						parent->_left = cur->_right;
		//					}
		//					else
		//					{
		//						parent->_right = cur->_right;
		//					}
		//				}
		//			}
		//			//左右有一个为空,右为空
		//			else if (cur->_right == nullptr)
		//			{
		//				if (cur == _root)//cur为根时
		//				{
		//					_root = _root->_left;
		//				}
		//				else//不为空时,判断此时cur为parent的左还是右
		//				{
		//					if (parent->_left == cur)
		//					{
		//						parent->_left = cur->_left;
		//					}
		//					else
		//					{
		//						parent->_right = cur->_left;
		//					}
		//				}
		//			}
		//			else  //cur的左右两边都不为空时
		//			{
		//				//leftMax为替代节点
		//				Node* leftMax = cur->_left;
		//				parent = cur;//这里不能给空,如果leftMax直接找到,parent就无法找到了
		//				while (leftMax->_right)//找到cur左边最大的那一个
		//				{
		//					parent = leftMax;
		//					leftMax = leftMax->_right;
		//				}
		//				//找到后交换
		//				swap(cur->_key, leftMax->_key);
		//				//不要忽略链接的问题,也就是为啥要给parent  cur的原因置空可能找不到parent
		//				if (parent->_left == leftMax)
		//				{
		//					parent->_left = leftMax->_left;
		//				}
		//				else
		//				{
		//					parent->_right = leftMax->_left;
		//				}
		//				cur = leftMax;
		//			}
		//			delete cur;
		//			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 (parent->_right == cur)
		//					{
		//						parent->_right = cur->_right;
		//					}
		//					else
		//					{
		//						parent->_left = cur->_right;
		//					}
		//				}
		//			}// 右为空
		//			else if (cur->_right == nullptr)
		//			{
		//				if (cur == _root)
		//				{
		//					_root = cur->_left;
		//				}
		//				else
		//				{
		//					if (parent->_right == cur)
		//					{
		//						parent->_right = cur->_left;
		//					}
		//					else
		//					{
		//						parent->_left = cur->_left;
		//					}
		//				}
		//			} // 左右都不为空 
		//			else
		//			{
		//				// 找替代节点
		//				Node* parent = cur;
		//				Node* leftMax = cur->_left;
		//				while (leftMax->_right)
		//				{
		//					parent = leftMax;
		//					leftMax = leftMax->_right;
		//				}

		//				swap(cur->_key, leftMax->_key);

		//				if (parent->_left == leftMax)
		//				{
		//					parent->_left = leftMax->_left;
		//				}
		//				else
		//				{
		//					parent->_right = leftMax->_left;
		//				}

		//				cur = leftMax;
		//			}

		//			delete cur;
		//			return true;
		//		}
		//	}

		//	return false;
		//}

		void InOrder()
		{
			_InOrder(_root);
			cout << endl;
		}
		bool FindR(const K & key)
		{
			return _FindR(_root, key);
		}
		bool Insert(const K & key)
		{
			return _Insert(_root, key);
		}
		bool Erase(const K& key)
		{
			return _Erase(_root, key);
		}

private: 
	    Node* copy(Node* root)
	    {
			if (root == nullptr)
			{
				return nullptr;
			}
				 
			Node* copyroot = new Node(root->_key);//
			copyroot->_left = copy(root->_left);
			copyroot->_right = copy(root->_right);
			return copyroot;
		}

	    
	    void Destroy(Node*& root)
	    {
			if (root == nullptr)
			{
				return;
			}
			Destroy(root->_left);
			Destroy(root->_right);
			delete root;
			root = NULL;

        }
	    bool _Erase(Node*& root,const K& key)
	    {
			if (root == nullptr)
			{
				return false;
			}
			if (root->_key < key)
			{
				return _Erase(root->_right, key);
			}
			else if (root->_key > key)
			{
				return _Erase(root->_left, key);

			}
			else//找到了
			{
				Node* del = root;
				// 1、左为空
				if (root->_left == nullptr)
				{
					root = root->_right;
				}
				// 2、右为空
				else if (root->_right == nullptr)
				{
					root = root->_left;
				}
				// 3、左右都不为空
				else
				{
					 
					//找到右边最大进行交换
					Node* LeftMax = root->_left;
					while (LeftMax->_right)
					{
						LeftMax = LeftMax->_right;
					}

					swap(root->_key, LeftMax->_key);
					return _Erase(root->_left, key);//不能传leftmax,为局部变量

				}
				delete del;
				return true;
			}
		}
		bool _Insert(Node*& root, const K& key)
		{
			if (root == nullptr)
			{
				//这里是否有疑问为啥可以直接new一个新,不考虑链接吗
				//原因在参数Node *& root,这里我们有一个引用,每次传递来的是对其区别名
				root = new Node(key); 
				return true;
			}
			if (root->_key < key)
			{
				return _Insert(root->_right, key);
			}
			else if (root->_key > key)
			{
				return _Insert(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);
			}
			if (root->_key > key)
			{
				return _FindR(root->_left, key);
			}
			else
			{
				return true;
			}

		}

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

			_InOrder(root->_left);
			cout << root->_key << " ";
			_InOrder(root->_right);
		}
		Node* _root;
};
//简单的测试代码
void test()
{
	int a[] = { 8, 3, 1, 10, 6, 4, 7, 14, 13 };
	BSTree<int> t;
	for (auto e : a)
	{
		t.Insert(e);
	}
	t.Erase(3);
	t.Erase(10);
	t.Erase(13);
	BSTree<int> t1(t);
	//t1 = t;

	t.InOrder();
	t1.InOrder();
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

大大白的小小白

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值