一.概念
二叉搜索树又称二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树
- 若它的左子树不为空,则左子树上所有节点的值都小于根节点的值
- 若它的右子树不为空,则右子树上所有节点的值都大于根节点的值
- 它的左右子树也分别为二叉搜索树
二.二叉搜索树的操作
1.查找
- 若根节点不为空:
- 如果根节点key ==查找key,返回true
- 如果根节点key<查找key,在它的右子树查找
- 如果根节点key>查找key,在它的左子树查找
- 否则,返回false
2.插入:
-
如果树是空树,则直接进行插入
-
否则,按照二叉搜索树的性质进行插入
如果在这棵树中要插入元素为7的新节点,则过程为: -
7大于根节点6,往根节点的右子树进行插入
-
根节点变为8,7小于8,则往8的左子树进行插入
-
8的左子树为空树,则直接进行插入
3.删除
- 如果要删除的节点不在这棵树中则返回false
- 如果要删除的节点只有左孩子节点,则让被删除节点的双亲节点指向被删除节点的左孩子节点
- 如果要删除的节点只有右孩子节点,则让被删除节点的双亲节点指向被删除节点的右孩子节点
- 如果要删除的节点有左右孩子节点,则要找它的替换节点后进行删除
如果要删除节点9,则让节点8的右子树指向节点10
如果要删除节点7(有左右孩子节点),则用节点6来替代节点7,之后删除节点7
三.实现
#pragma once
template<class K,class V>
struct BSTreeNode
{
BSTreeNode<K,V>* _left;
BSTreeNode<K, V>* _right;
std::pair<K, V> _kv;
BSTreeNode(const std::pair<K, V>& kv)
:_left(nullptr)
, _right(nullptr)
, _kv(kv)
{}
};
template<class K,class V>
class BSTree
{
typedef BSTreeNode<K, V> Node;
public:
BSTree()
:_root(nullptr)
{}
Node* Find(const K& k)
{
if (_root == nullptr)
return NULL;
Node* cur = _root;
while (cur)
{
if (cur->_kv.first < k)
cur = cur->_right;
else if (cur->_kv.first>k)
cur = cur->_left;
else
{
cout<<cur->_kv.first<<endl;
return cur;
}
}
return NULL;
}
bool Insert(const std::pair<K, V>& kv)
{
if (_root == nullptr)
{
_root = new Node(kv);
return true;
}
Node* cur = _root;
Node* parent = _root;
while (cur)
{
if (cur->_kv.first > kv.first)
{
parent = cur;
cur = cur->_left;
}
else if (cur->_kv.first<kv.first)
{
parent = cur;
cur = cur->_right;
}
else if (cur->_kv == kv)
{
return false;
}
}
cur = new Node(kv);
if (parent->_kv.first > kv.first)
parent->_left = cur;
else
parent->_right = cur;
return true;
}
bool Erase(const K& k)
{
if (_root == nullptr)
return false;
Node* cur = _root;
Node* parent = _root;
while (cur)
{
if (cur->_kv.first > k)
{
parent = cur;
cur = cur->_left;
}
else if (cur->_kv.first < k)
{
parent = cur;
cur = cur->_right;
}
else //找到删除节点
{
Node* del = cur;
if (!cur->_left) //左节点为空
{
if (parent == _root)
{
_root = cur->_right;
}
else
{
if (parent->_left == cur)
{
parent->_left = cur->_right;
}
else
{
parent->_right = cur->_right;
}
}
}
else if (!cur->_right) //右节点为空
{
if (parent == _root)
{
_root = cur->_left;
}
else
{
if (parent->_left == cur)
{
parent->_left = cur->_left;
}
else
{
parent->_right = cur->_left;
}
}
}
else //左右节点都不为空
{
Node* prereplace=cur;
Node* replace = cur->_right;
while (replace->_left)
{
prereplace = replace;
replace = replace->_left;
}
cur->_kv = replace->_kv;
del = replace;
//删除替代的最左节点
if (prereplace->_left == replace)
{
prereplace->_left = replace->_right;
}
else
{
prereplace->_right = replace->_right;
}
}
delete del;
return true;
}
}
return false;
}
void Inorder()
{
return _Inorder(_root);
}
void _Inorder(Node* root)
{
if (root == nullptr)
return;
_Inorder(root->_left);
cout << root->_kv.first<<' ';
_Inorder(root->_right);
}
private:
Node* _root;
};
void TestBSTree()
{
int a[] = { 5, 3, 4, 1, 7, 8, 2, 6, 0, 9,0};
BSTree<int, int> t;
for (auto e : a)
{
t.Insert(std::make_pair(e, e));
}
t.Inorder();
std::cout << std::endl;
t.Erase(2);
t.Erase(8);
t.Erase(1);
t.Erase(7);
//t.Erase(2);
t.Inorder();
}