二叉搜索树与Key/Value模型

前言

前面的文章我们介绍了二叉搜索树的简单实现,对于二叉搜索树而言,它的最大作用是用来查找数据的,那么根据这一特点,我们可以设计一个Key/value模型,这个Key/Value模型就是根据一个值去找另一个值,例如:简单的字典实现、门禁系统、图书管理系统等,那么接下来我们将以二叉搜索树为底层,去介绍Key/value的原理。

参考文章:

数据结构(四)——二叉搜索树的实现(C++版)

Key模型的封装

我们对二叉搜索树的代码用命名空间封装一次,并增加构造函数、拷贝构造函数,析构函数等,这样我们就写出了一个完整的Key模型

拷贝构造函数

对于拷贝构造函数,我们遵循先序遍历,即:按照根节点,左子树,右子树的顺序递归遍历,为了方便用户使用,并访问私有,我们在类里面提供一个Copy函数,用来先序遍历,然后在拷贝构造函数调用这个函数,即可完成拷贝构造,其代码如下所示:

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

拷贝构造函数调用Copy函数:

BinarySearchTree(const BinarySearchTree& t)
{
	_root = Copy(t._root);
}

析构函数

与拷贝构造函数类似,我们同样在类里面提供一个Destroy函数,用来完成数据的清理,析构函数则调用这个Destroy函数。对于二叉树的销毁,我们同样采用递归完成,我们这里采用后序遍历,即:左子树、右子树、根节点,其代码如下所示:

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

析构函数如下所示:

~BinarySearchTree()
{
	Destroy(_root);
	_root = nullptr;
}

Key模型代码如下所示

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

	template
	class BinarySearchTree
	{
		typedef BinarySearchTreeNode Node;
	public:
		BinarySearchTree() = default;
		BinarySearchTree(const BinarySearchTree& t)
		{
			_root = Copy(t._root);
		}
		~BinarySearchTree()
		{
			Destroy(_root);
			_root = nullptr;
		}
		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 Insert(const K& key)
		{
			if (_root == nullptr)
			{
				_root = new Node(key);
				return true;
			}
			Node* cur = _root;
			Node* parent = nullptr;
			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->_left = cur;
			}
			else
			{
				parent->_right = cur;
			}
			return true;
		}

		bool Erase(const K& key)
		{
			Node* cur = _root;
			Node* parent = nullptr;
			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 (parent == nullptr)
							{
								_root = cur->_right;
							}
							else
							{
								if (parent->_left == cur)
								{
									parent->_left = cur->_right;
								}
								else
								{
									parent->_right = cur->_right;
								}
							}
							delete cur;
							return true;
						}
						else
						{
							if (cur->_right == nullptr)
							{
								if (parent == nullptr)
								{
									_root = cur->_left;
								}
								else
								{
									if (parent->_left == cur)
									{
										parent->_left = cur->_left;
									}
									else
									{
										parent->_right = cur->_left;
									}
								}
								delete cur;
								return true;
							}
							else
							{
								Node* RightMin = cur->_right;
								Node* RightMinParent = cur;
								while (RightMin->_left)
								{
									RightMinParent = RightMin;
									RightMin = RightMin->_left;
								}
								cur->_key = RightMin->_left;
								if (RightMinParent->_left = RightMin)
								{
									RightMinParent->_left = RightMin->_right;
								}
								else
								{
									RightMinParent->_right = RightMin->_right;
								}
								delete cur;
								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:
		void Destroy(Node*root)
		{
			if (root == nullptr)
			{
				return;
			}
			Destroy(root->_left);
			Destroy(root->_right);
			delete root;
		}
	private:
		Node* Copy(Node* root)
		{
			if (root == nullptr)
			{
				return nullptr;
			}
			Node* newNode = new Node(root->_key);
			newNode->_left = Copy(root->_left);
			newNode->_right = Copy(root->_right);
			return newNode;
		}
	private:
		Node* _root = nullptr;

	};
}

Key/Value模型的封装

与key模型类似,但是在模板参数这一栏,我们多了一个模板参数value,其代码如下所示:

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

	template
	class BinarySearchTree
	{
		typedef BinarySearchTreeNode Node;
	public:
		BinarySearchTree()=default;
		BinarySearchTree(const BinarySearchTree& t)
		{
			_root = Copy(t._root);
		}
		~BinarySearchTree()
		{
			Destroy(_root);
			_root = nullptr;
		}
		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 Insert(const K& key,const V&value)
		{
			if (_root == nullptr)
			{
				_root = new Node(key,value);
				return;
			}
			Node* cur = _root;
			Node* parent = nullptr;
			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->_left = cur;
			}
			else
			{
				parent->_right = cur;
			}
			return true;
		}

		bool Erase(const K& key)
		{
			Node* cur = _root;
			Node* parent = nullptr;
			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 (parent == nullptr)
							{
								_root = cur->_right;
							}
							else
							{
								if (parent->_left == cur)
								{
									parent->_left = cur->_right;
								}
								else
								{
									parent->_right = cur->_right;
								}
							}
							delete cur;
							return true;
						}
						else
						{
							if (cur->_right == nullptr)
							{
								if (parent == nullptr)
								{
									_root = cur->_left;
								}
								else
								{
									if (parent->_left == cur)
									{
										parent->_left = cur->_left;
									}
									else
									{
										parent->_right = cur->_left;
									}
								}
								delete cur;
								return true;
							}
							else
							{
								Node* RightMin = cur->_right;
								Node* RightMinParent = cur;
								while (RightMin->_left)
								{
									RightMinParent = RightMin;
									RightMin = RightMin->_left;
								}
								cur->_key = RightMin->_left;
								if (RightMinParent->_left = RightMin)
								{
									RightMinParent->_left = RightMin->_right;
								}
								else
								{
									RightMinParent->_right = RightMin->_right;
								}
								delete cur;
								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 << " ";
			_InOrder(root->_right);
		}
		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, root->_value);
			newRoot->_left = Copy(root->_left);
			newRoot->_right = Copy(root->_right);
			return newRoot;
		}
	private:
		Node* _root = nullptr;

	};
}

你可能感兴趣的:(c++)