前面的文章我们介绍了二叉搜索树的简单实现,对于二叉搜索树而言,它的最大作用是用来查找数据的,那么根据这一特点,我们可以设计一个Key/value模型,这个Key/Value模型就是根据一个值去找另一个值,例如:简单的字典实现、门禁系统、图书管理系统等,那么接下来我们将以二叉搜索树为底层,去介绍Key/value的原理。
参考文章:
数据结构(四)——二叉搜索树的实现(C++版)
我们对二叉搜索树的代码用命名空间封装一次,并增加构造函数、拷贝构造函数,析构函数等,这样我们就写出了一个完整的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;
}
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,其代码如下所示:
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;
};
}