二叉搜索树

目录

一、基本函数实现

(一)结点定义

(二)插入结点

1. 非递归插入

2. 递归插入

(三)查找

1. 非递归

2. 递归

(四)删除

1. 删除情况分析

2. 非递归

3. 递归

(五)中序遍历

(六)拷贝树和销毁

(七)构造、拷贝构造、析构和赋值重载

二、完整代码

1. BinarySearchTree.h

2. 测试1

3. 测试2

4. 测试3

5. 测试4 

三、二叉搜索树的应用

(一) K模型

(二)KV模型

1. 结点定义

2. 完整代码


一、基本函数实现

(一)结点定义

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

(二)插入结点

1. 非递归插入

bool Insert(const K& key)//插入
{
	if (_root == nullptr)
	{
		_root = new Node(key);
		return true;
	}

	Node* cur = _root;
	Node* parent = nullptr;//cur的父亲结点
	while (cur)
	{
		parent = cur;

		if (key > cur->_key)//key的值比cur的值大,就去cur的右边
		{
			cur = cur->_right;
		}
		else if (key < cur->_key)//key的值比cur的值小,就去cur的左边
		{
			cur = cur->_left;
		}
		else
		{
			return false;
		}
	}

	cur = new Node(key);
	//连接
	if (key > parent->_key)
	{
		parent->_right = cur;
	}
	else
	{
		parent->_left = cur;
	}
	return true;
}

2. 递归插入

bool InsertR(const K& key)//递归插入
{
	return _InsertR(this->_root, key);通过_InsertR函数拿到私有成员_root,然后进行递归
}
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;
	}
}

(三)查找

1. 非递归

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

2. 递归

bool FindR(const K& key)//递归查找
{
	return _FindR(this->_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. 删除情况分析

二叉搜索树_第1张图片

二叉搜索树_第2张图片 

2. 非递归

bool Erase(const K& key)//删除结点
{
	Node* cur = _root;
	Node* parent = nullptr;//parent是删除结点cur的父结点
	while (cur)//先找到key值所在的结点
	{
		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)//删除的是根结点
				{
					_root = cur->_right;
				}
				else//删除的不是根结点
				{
					if (cur == parent->_left)//cur是父结点的左结点
					{
						parent->_left = cur->_right;
					}
					else//cur是父结点的右结点
					{
						parent->_right = cur->_right;
					}
				}
				delete cur;
				return true;
			}
			else if (cur->_right == nullptr)//删除的结点,只存在左子树)
			{
				if (cur == _root)//删除的是根结点
				{
					_root = cur->_left;
				}
				else
				{
					if (cur == parent->_left)//cur是父结点的左结点
					{
						parent->_left = cur->_left;
					}
					else//cur是父结点的右结点
					{
						parent->_right = cur->_left;
					}
				}
				delete cur;
				return true;
			}
			else//左右子树都不为空
			{
				//找右子树的最小结点
				Node* Minparent = cur;//右子树的最小结点的父结点
				Node* MinNode = cur->_right;//找cur右子树的最小结点
				while (MinNode->_left)
				{
					Minparent = MinNode;
					MinNode = MinNode->_left;
				}
				swap(MinNode->_key, cur->_key);//交换最小结点和删除结点的值

				if (MinNode == Minparent->_left)//
				{
					Minparent->_left = MinNode->_right;
				}
				else//说明cur右子树的最小结点就是cur右子树的根结点
				{
					Minparent->_right = MinNode->_right;
				}
				delete MinNode;
				return true;
			}
		}
	}
	return false; //没有找到待删除结点,删除失败
}

3. 递归

bool EraseR(const K& key)//递归删除
{
	return _EraseR(this->_root, key);
}
bool _EraseR(Node*& root, const K& key)
{
	if (_root == nullptr)
	{
		return false;
	}

	if (key > root->_key)
	{
		return _EraseR(root->_right, key);//递归到右边
	}
	else if (key < root->_key)
	{
		return _EraseR(root->_left, key);
	}
	else //找到了等于key的结点
	{
		if (root->_left == nullptr)//删除的结点,只存在右子树(或者左右子树都不存在)
		{
			Node* del = root;//先保存删除结点
			root = root->_right;//更新root

			delete del;//释放结点
			return true;
		}
		else if (root->_right == nullptr)
		{
			Node* del = root;//先保存删除结点
			root = root->_left;//更新root

			delete del;//释放结点
			return true;
		}
		else//左右子树都存在
		{
			//找删除结点右子树的最小结点
			Node* MinNode = root->_right;//开始指向右子树的根结点

			while (MinNode->_left)
			{
				MinNode = MinNode->_left;
			}

			swap(root->_key, MinNode->_key);//删除结点的值的值交换到了右子树上

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

(五)中序遍历

void InOrder()//中序遍历
{
	_InOrder(this->_root);//通过_InOrder函数拿到私有成员_root,然后进行递归
}
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;
	}
}

(六)拷贝树和销毁

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

(七)构造、拷贝构造、析构和赋值重载

BSTree() :_root(nullptr)//在构造函数中初始化私有成员_root 为 nullptr
{}
~BSTree()//析构函数
{
	Destory();
}
BSTree(const BSTree& t)//拷贝构造函数
{
	this->_root = Copy(t._root);
}

BSTree& operator=(BSTree t)//赋值重载
{
	swap(this->_root, t._root);
	return *this;
}

二、完整代码

1. BinarySearchTree.h

#pragma once
#include
using namespace std;
template
struct BSTreeNode
{
	BSTreeNode* _left;
	BSTreeNode* _right;
	K _key;
	BSTreeNode(const K& key)
		:_left(nullptr)
		, _right(nullptr)
		, _key(key)
	{}
};

template
class BSTree
{
	typedef BSTreeNode Node;
public:
	BSTree() :_root(nullptr)//在构造函数中初始化私有成员_root 为 nullptr
	{}
	~BSTree()//析构函数
	{
		Destory();
	}
	BSTree(const BSTree& t)//拷贝构造函数
	{
		this->_root = Copy(t._root);
	}

	BSTree& operator=(BSTree t)//赋值重载
	{
		swap(this->_root, t._root);
		return *this;
	}

	void SetRoot(BSTreeNode* root)//设置根结点
	{
		_root = root;
	}
	void Destory()//释放结点
	{
		_Destroy(this->_root);
	}

	bool Insert(const K& key)//插入
	{
		if (_root == nullptr)
		{
			_root = new Node(key);
			return true;
		}

		Node* cur = _root;
		Node* parent = nullptr;//cur的父亲结点
		while (cur)
		{
			parent = cur;

			if (key > cur->_key)//key的值比cur的值大,就去cur的右边
			{
				cur = cur->_right;
			}
			else if (key < cur->_key)//key的值比cur的值小,就去cur的左边
			{
				cur = cur->_left;
			}
			else
			{
				return false;
			}
		}

		cur = new Node(key);
		//连接
		if (key > parent->_key)
		{
			parent->_right = cur;
		}
		else
		{
			parent->_left = cur;
		}
		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 Erase(const K& key)//删除结点
	{
		Node* cur = _root;
		Node* parent = nullptr;//parent是删除结点cur的父结点
		while (cur)//先找到key值所在的结点
		{
			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)//删除的是根结点
					{
						_root = cur->_right;
					}
					else//删除的不是根结点
					{
						if (cur == parent->_left)//cur是父结点的左结点
						{
							parent->_left = cur->_right;
						}
						else//cur是父结点的右结点
						{
							parent->_right = cur->_right;
						}
					}
					delete cur;
					return true;
				}
				else if (cur->_right == nullptr)//删除的结点,只存在左子树)
				{
					if (cur == _root)//删除的是根结点
					{
						_root = cur->_left;
					}
					else
					{
						if (cur == parent->_left)//cur是父结点的左结点
						{
							parent->_left = cur->_left;
						}
						else//cur是父结点的右结点
						{
							parent->_right = cur->_left;
						}
					}
					delete cur;
					return true;
				}
				else//左右子树都不为空
				{
					//找右子树的最小结点
					Node* Minparent = cur;//右子树的最小结点的父结点
					Node* MinNode = cur->_right;//找cur右子树的最小结点
					while (MinNode->_left)
					{
						Minparent = MinNode;
						MinNode = MinNode->_left;
					}
					swap(MinNode->_key, cur->_key);//交换最小结点和删除结点的值
					
					if (MinNode == Minparent->_left)//
					{
						Minparent->_left = MinNode->_right;
					}
					else//说明cur右子树的最小结点就是cur右子树的根结点
					{
						Minparent->_right = MinNode->_right;
					}
					delete MinNode;
					return true;
				}
			}
		}
		return false; //没有找到待删除结点,删除失败
	}

	//递归
	bool InsertR(const K& key)//递归插入
	{
		return _InsertR(this->_root, key);
	}
	bool FindR(const K& key)//递归查找
	{
		return _FindR(this->_root, key);
	}
	bool EraseR(const K& key)//递归删除
	{
		return _EraseR(this->_root, key);
	}
	void InOrder()//中序遍历
	{
		_InOrder(this->_root);//通过_InOrder函数拿到私有成员_root,然后进行递归
	}
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 _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 _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 _EraseR(Node*& root, const K& key)
	{
		if (_root == nullptr)
		{
			return false;
		}

		if (key > root->_key)
		{
			return _EraseR(root->_right, key);//递归到右边
		}
		else if (key < root->_key)
		{
			return _EraseR(root->_left, key);
		}
		else //找到了等于key的结点
		{
			if (root->_left == nullptr)//删除的结点,只存在右子树(或者左右子树都不存在)
			{
				Node* del = root;//先保存删除结点
				root = root->_right;//更新root

				delete del;//释放结点
				return true;
			}
			else if (root->_right == nullptr)
			{
				Node* del = root;//先保存删除结点
				root = root->_left;//更新root

				delete del;//释放结点
				return true;
			}
			else//左右子树都存在
			{
				//找删除结点右子树的最小结点
				Node* MinNode = root->_right;//开始指向右子树的根结点

				while (MinNode->_left)
				{
					MinNode = MinNode->_left;
				}

				swap(root->_key, MinNode->_key);//删除结点的值的值交换到了右子树上

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

	void _InOrder(Node* root)//中序遍历
	{
		if (root == nullptr)
		{
			return;
		}
		_InOrder(root->_left);
		cout << root->_key << " ";
		_InOrder(root->_right);
	}
private:
	Node* _root;
};

2. 测试1

#include"BinarySearchTree.h"
int main()
{
	int data[] = { 1, 5, 2, 9, 7, 3, 8, 17, 15, 4};
	//创建树
	BSTree T;
	for (int i = 0; i < sizeof(data)/sizeof(data[0]); i++)
	{
		T.Insert(data[i]);
	}

	T.InOrder();//中序遍历

	cout << endl;
	if (T.Find(89) == true)
	{
		cout << "找到了" << endl;
	}
	else
	{
		cout << "没有找到" << endl;
	}
	return 0;
}

3. 测试2

#include"BinarySearchTree.h"
int main()
{
	//手动链接结点,创建T2
	BSTree T2;
	BSTreeNode* Node1 = new BSTreeNode(8);
	BSTreeNode* Node2 = new BSTreeNode(3);
	BSTreeNode* Node3 = new BSTreeNode(10);
	BSTreeNode* Node4 = new BSTreeNode(1);
	BSTreeNode* Node5 = new BSTreeNode(6);
	BSTreeNode* Node6 = new BSTreeNode(14);
	BSTreeNode* Node7 = new BSTreeNode(4);
	BSTreeNode* Node8 = new BSTreeNode(7);
	BSTreeNode* Node9 = new BSTreeNode(13);
	Node1->_left = Node2;
	Node1->_right = Node3;
	Node2->_left = Node4;
	Node2->_right = Node5;
	Node3->_right = Node6;
	Node5->_left = Node7;
	Node5->_right = Node8;
	Node6->_left = Node9;
	T2.SetRoot(Node1);
	cout << "删除10之前:";
	T2.InOrder();//中序遍历

	T2.Erase(10);
	cout << endl;
	cout << "删除10之后:";
	T2.InOrder();

	T2.Erase(3);
	cout << endl;
	cout << "删除3之后:" ;
	T2.InOrder();

	return 0;
}

4. 测试3

#include"BinarySearchTree.h"
int main()
{
	//手动链接结点,创建T2
	BSTree T2;
	BSTreeNode* Node1 = new BSTreeNode(8);
	BSTreeNode* Node2 = new BSTreeNode(3);
	BSTreeNode* Node3 = new BSTreeNode(10);
	BSTreeNode* Node4 = new BSTreeNode(1);
	BSTreeNode* Node5 = new BSTreeNode(6);
	BSTreeNode* Node6 = new BSTreeNode(14);
	BSTreeNode* Node7 = new BSTreeNode(4);
	BSTreeNode* Node8 = new BSTreeNode(7);
	BSTreeNode* Node9 = new BSTreeNode(13);
	Node1->_left = Node2;
	Node1->_right = Node3;
	Node2->_left = Node4;
	Node2->_right = Node5;
	Node3->_right = Node6;
	Node5->_left = Node7;
	Node5->_right = Node8;
	Node6->_left = Node9;
	T2.SetRoot(Node1);

	//递归
	//T2.InOrder();
	//T2.InsertR(9);
	//cout << endl;
	//cout << "插入9之后:";
	//T2.InOrder();


	//cout << "删除3之前:";
	//T2.InOrder();
	//T2.EraseR(3);
	//cout << endl;
	//cout << "删除3之后:";
	//T2.InOrder();


	//cout << "删除10之前:";
	//T2.InOrder();
	//T2.EraseR(10);
	//cout << endl;
	//cout << "删除10之后:";
	//T2.InOrder();

	if (T2.FindR(4) == true)
	{
		cout << "找到了" << endl;
	}
	else
	{
		cout << "没有找到" << endl;
	}
	return 0;
}

5. 测试4 

#include"BinarySearchTree.h"
int main()
{
	//手动链接结点,创建T
	BSTree T;
	BSTreeNode* Node1 = new BSTreeNode(8);
	BSTreeNode* Node2 = new BSTreeNode(3);
	BSTreeNode* Node3 = new BSTreeNode(10);
	BSTreeNode* Node4 = new BSTreeNode(1);
	BSTreeNode* Node5 = new BSTreeNode(6);
	BSTreeNode* Node6 = new BSTreeNode(14);
	BSTreeNode* Node7 = new BSTreeNode(4);
	BSTreeNode* Node8 = new BSTreeNode(7);
	BSTreeNode* Node9 = new BSTreeNode(13);
	Node1->_left = Node2;
	Node1->_right = Node3;
	Node2->_left = Node4;
	Node2->_right = Node5;
	Node3->_right = Node6;
	Node5->_left = Node7;
	Node5->_right = Node8;
	Node6->_left = Node9;
	T.SetRoot(Node1);

	BSTree T2(T);//拷贝构造
	cout << "T2:" ;
	T2.InOrder();
	cout << endl;


	int data[] = { 1, 5, 2, 9, 7, 3, 8, 17, 15, 4};
	//创建树
	BSTree T3;
	for (int i = 0; i < sizeof(data)/sizeof(data[0]); i++)
	{
		T3.Insert(data[i]);
	}
	cout << "T3:";
	T3.InOrder();
	cout << endl;
	cout << "T3被T2赋值以后:";
	T3 = T2;
	T3.InOrder();
	cout << endl;

	cout << "析构以后T2:";
	T2.~BSTree();


	return 0;
}

三、二叉搜索树的应用

(一) K模型

  • K模型即只有key作为关键码,结构中只需要存储Key即可,关键码即为需要搜索到的值。
  • 比如:给一个单词word,判断该单词是否拼写正确,具体方式如下:
  • 以词库中所有单词集合中的每个单词作为key,构建一棵二叉搜索树
  • 在二叉搜索树中检索该单词是否存在,存在则拼写正确,不存在则拼写错误

(二)KV模型

  • 每一个关键码key,都有与之对应的值Value,即的键值对。该种方式在现实生活中非常常见:
  • 比如英汉词典就是英文与中文的对应关系,通过英文可以快速找到与其对应的中文,英文单词与其对应的中文就构成一种键值对;
  • 再比如统计单词次数,统计成功后,给定单词就可快速找到其出现的次数,单词与其出现次数就是就构成一种键值对

1. 结点定义

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

2. 完整代码

#pragma once
#include
using namespace std;
template
struct BSTreeNode
{
	BSTreeNode* _left;
	BSTreeNode* _right;
	K _key;
	V _value;
	BSTreeNode(const K& key, const V& value)
		:_left(nullptr)
		, _right(nullptr)
		, _key(key)
		,_value(value)
	{}
};

template
class BSTree
{
	typedef BSTreeNode Node;
public:
	BSTree() :_root(nullptr)//在构造函数中初始化私有成员_root 为 nullptr
	{}
	~BSTree()//析构函数
	{
		Destory();
	}
	BSTree(const BSTree& t)//拷贝构造函数
	{
		this->_root = Copy(t._root);
	}

	BSTree& operator=(BSTree t)//赋值重载
	{
		swap(this->_root, t._root);
		return *this;
	}

	void SetRoot(BSTreeNode* root)//设置根结点
	{
		_root = root;
	}
	void Destory()//释放结点
	{
		_Destroy(this->_root);
	}

	bool Insert(const K& key, const V& value)//插入
	{
		if (_root == nullptr)
		{
			_root = new Node(key, value);
			return true;
		}

		Node* cur = _root;
		Node* parent = nullptr;//cur的父亲结点
		while (cur)
		{
			parent = cur;

			if (key > cur->_key)//key的值比cur的值大,就去cur的右边
			{
				cur = cur->_right;
			}
			else if (key < cur->_key)//key的值比cur的值小,就去cur的左边
			{
				cur = cur->_left;
			}
			else
			{
				return false;
			}
		}

		cur = new Node(key, value);
		//连接
		if (key > parent->_key)
		{
			parent->_right = cur;
		}
		else
		{
			parent->_left = cur;
		}
		return true;
	}
	Node* 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 cur;
			}
		}
		return nullptr;
	}
	bool Erase(const K& key)//删除结点
	{
		Node* cur = _root;
		Node* parent = nullptr;//parent是删除结点cur的父结点
		while (cur)//先找到key值所在的结点
		{
			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)//删除的是根结点
					{
						_root = cur->_right;
					}
					else//删除的不是根结点
					{
						if (cur == parent->_left)//cur是父结点的左结点
						{
							parent->_left = cur->_right;
						}
						else//cur是父结点的右结点
						{
							parent->_right = cur->_right;
						}
					}
					delete cur;
					return true;
				}
				else if (cur->_right == nullptr)//删除的结点,只存在左子树)
				{
					if (cur == _root)//删除的是根结点
					{
						_root = cur->_left;
					}
					else
					{
						if (cur == parent->_left)//cur是父结点的左结点
						{
							parent->_left = cur->_left;
						}
						else//cur是父结点的右结点
						{
							parent->_right = cur->_left;
						}
					}
					delete cur;
					return true;
				}
				else//左右子树都不为空
				{
					//找右子树的最小结点
					Node* Minparent = cur;//右子树的最小结点的父结点
					Node* MinNode = cur->_right;//找cur右子树的最小结点
					while (MinNode->_left)
					{
						Minparent = MinNode;
						MinNode = MinNode->_left;
					}
					swap(MinNode->_key, cur->_key);//交换最小结点和删除结点的值
					
					if (MinNode == Minparent->_left)//
					{
						Minparent->_left = MinNode->_right;
					}
					else//说明cur右子树的最小结点就是cur右子树的根结点
					{
						Minparent->_right = MinNode->_right;
					}
					delete MinNode;
					return true;
				}
			}
		}
		return false; //没有找到待删除结点,删除失败
	}

	//递归
	bool InsertR(const K& key)//递归插入
	{
		return _InsertR(this->_root, key);
	}
	Node* FindR(const K& key)//递归查找
	{
		return _FindR(this->_root, key);
	}
	bool EraseR(const K& key)//递归删除
	{
		return _EraseR(this->_root, key);
	}
	void InOrder()//中序遍历
	{
		_InOrder(this->_root);//通过_InOrder函数拿到私有成员_root,然后进行递归
	}
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 _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;
		}
	}
	Node* _FindR(Node* root, const K& key)
	{
		if (root == nullptr)
		{
			return nullptr;
		}

		if (key > root->_key)
		{
			return _FindR(root->_right, key);//递归到右边
		}
		else if (key < root->_key)
		{
			return _FindR(root->_left, key);//递归到左边
		}
		else//存在相等的值
		{
			return root;
		}
	}
	bool _EraseR(Node*& root, const K& key)
	{
		if (_root == nullptr)
		{
			return false;
		}

		if (key > root->_key)
		{
			return _EraseR(root->_right, key);//递归到右边
		}
		else if (key < root->_key)
		{
			return _EraseR(root->_left, key);
		}
		else //找到了等于key的结点
		{
			if (root->_left == nullptr)//删除的结点,只存在右子树(或者左右子树都不存在)
			{
				Node* del = root;//先保存删除结点
				root = root->_right;//更新root

				delete del;//释放结点
				return true;
			}
			else if (root->_right == nullptr)
			{
				Node* del = root;//先保存删除结点
				root = root->_left;//更新root

				delete del;//释放结点
				return true;
			}
			else//左右子树都存在
			{
				//找删除结点右子树的最小结点
				Node* MinNode = root->_right;//开始指向右子树的根结点

				while (MinNode->_left)
				{
					MinNode = MinNode->_left;
				}

				swap(root->_key, MinNode->_key);//删除结点的值的值交换到了右子树上

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

	void _InOrder(Node* root)//中序遍历
	{
		if (root == nullptr)
		{
			return;
		}
		_InOrder(root->_left);
		cout << root->_key << " ";
		_InOrder(root->_right);
	}
private:
	Node* _root;
};
#include"BinarySearchTree.h"
#include
int main()
{
	BSTree dict;
	dict.Insert("sort", "排序");
	dict.Insert("left", "左边");
	dict.Insert("right", "右边");
	dict.Insert("insert", "插入");
	dict.Insert("key", "key值");

	string str;
	while (cin >> str)
	{
		BSTreeNode* ret = dict.FindR(str);
		if (ret)
		{
			cout << ret->_value << endl;
		}
		else
		{
			cout << "不在字典中" << endl;
		}
	}

	return 0;
}

你可能感兴趣的:(数据结构(精),1024程序员节)