一、定义
二叉搜索树又称二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树:
若它的左子树不为空,则左子树上所有节点的值都小于根节点的值
若它的右子树不为空,则右子树上所有节点的值都大于根节点的值
它的左右子树也分别为二叉搜索树
二、实现
2.1构建二叉搜索树
template<class K, class V>
struct BSTreeNode {
BSTreeNode<K, V>* _left;
BSTreeNode<K, V>* _right;
K _key;
V _value;
BSTreeNode(const K& key, const V& value)
:_left(nullptr)
, _right(nullptr)
, _key(key)
, _value(value)
{}
};
在二叉树的模型中,有K模型和KV模型,就是一个结点一个值和一个结点一个键值对两个模型。
一个值的很简单,而KV模型就是一个结点存放一个key和一个value。
2.2插入
bool Insert(const K& key, const V& value) {
if (_root == nullptr) { _root = new Node(key, value);
return true;
}
Node* cur = _root;
Node* parent = _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 < cur->_key) {
parent->_right = cur;
}
else {
parent->_left = cur;
}
return true;
}
2.3查找
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;
}
2.4删除
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
{
//找到当前位置后且左空,且位于parent的左,
//则删除该位置后的parent左就变为cur的右
//如果当前位置位于parren右,且且左空,则paret的右即为cur的右
if (cur == parent->_left) {
parent->_left = cur->_right;
}
else {
parent->_right = cur->_right;
}
}
delete cur;
cur = nullptr;
}//删除右位置为空
else if (cur->_right == nullptr)
{
if (cur == _root) {
_root = cur->_left;
}
else
{
if (cur == parent->_left) {
parent->_left = cur->_right;
}
else {
parent->_right = cur->_right;
}
}
delete cur;
cur = nullptr;
}
else
{//替换法删除 //右子树最小节点---右子树最左节点
Node* minparent = cur;
Node* min = cur->_right;
while (min->_left)
{
minparent = min;
min = min->_left;
}
swap(cur->_key, min->_key);
if (minparent->_left == min)
minparent->_left = min->_right;
else
minparent->_right = min->_right;
delete min;
}return true;
}
}
}