二叉搜索树又称二叉查找树,它是一颗空树或者是具有以下特征的树:
1、若它的左子树不为空,则左子树上所有结点的值均小于它的根结点的值;
2、若它的右子树不为空,则右子树上所有结点的值均大于它的根结点的值;
3、它的左、右子树也分别为二叉搜索树。
二叉搜索树有查找,插入,删除等操作;有递归和非递归两种实现方法。
查找一个节点:树为空则返回空;若要查找的节点等于根节点,返回根节点;若要查找的节点大于根节点,递归查找右子树,反之递归查找左子树。
BSTreeNode<K, V>* _Find(BSTreeNode<K, V>* root, const K& key)
{
if (NULL == root)
{
return false;
}
if (key > root->_key)
{
_Find(root->_right, key);
}
else if (key < root->_key)
{
_Find(root->_left, key);
}
else
{
return root;
}
}
插入一个节点:如果树为空,新建一个节点做为根节点;若要插入的节点等于根节点,返回false;若要插入的节点大于根节点,递归插入右子树,反之递归插入左子树。
bool _Insert(BSTreeNode<K, V>* root, const K& key, const V& value)
{
if (root != NULL)
{
if (key > root->_key)
{
_Insert(root->_right, key, value);
if (root->_right==NULL)
{
root->_right = new BSTreeNode<K, V>(key, value);
return true;
}
}
else if (key < root->_key)
{
_Insert(root->_left, key, value);
if (root->_left==NULL)
{
root->_left = new BSTreeNode<K, V>(key, value);
return true;
}
}
else if (key == root->_key)
{
return false;
}
}
}
删除一个节点:分三种情况
(1)待删除节点没有孩子:
直接删除
(2)待删除节点只有一个孩子:
若cur的左孩子为空,让cur的parent指向cur的右孩子;
若cur的右孩子为空,让cur的parent指向cur的左孩子。
(情况1和情况2可以归为一类)
(3)待删除节点有两个孩子:
第一步:先找到cur右孩子的最左节点(保证了比cur左子树所有节点都大,比右子树其他节点都小)
第二步:交换最左节点和cur的值(在第一步的基础上,交换后还是二叉搜索树)
第三步:删除最左节点(问题转化成了前两种情况)
完整代码:
#include<iostream>
#include<cassert>
using namespace std;
template<class K, class V>
struct BSTreeNode
{
K _key;
V _value;
BSTreeNode<K, V>* _left;
BSTreeNode<K, V>* _right;
BSTreeNode(const K& key, const V& value)
:_key(key)
, _value(value)
, _left(NULL)
, _right(NULL)
{}
};
template<class K, class V>
class BSTree
{
public:
BSTree()
:_root(NULL)
{}
//非递归
bool Insert_NR(const K& key, const V& value)
{
if (NULL == _root)
{
_root = new BSTreeNode<K, V>(key, value);
}
else
{
BSTreeNode<K, V>* cur = _root;
BSTreeNode<K, V>* parent = NULL;
while (cur)
{
if (key > cur->_key)
{
parent = cur;
cur = cur->_right;
}
else if (key < cur->_key)
{
parent = cur;
cur = cur->_left;
}
else
{
return false;
}
}
if (key < parent->_key)
{
parent->_left = new BSTreeNode<K, V>(key, value);
}
else
{
parent->_right = new BSTreeNode<K, V>(key, value);
}
}
return true;
}
bool Insert_R(const K& key, const V& value)
{
if (NULL == _root)
{
_root = new BSTreeNode<K, V>(key, value);
return true;
}
_Insert(_root, key, value);
}
bool Remove_NR(const K& key)
{
if (NULL == _root)
{
return false;
}
BSTreeNode<K, V>* del = _root;
BSTreeNode<K, V>* parent = NULL;
while (del)
{
if (key > del->_key)
{
parent = del;
del = del->_right;
}
else if (key < del->_key)
{
parent = del;
del = del->_left;
}
else
{
break;
}
}
if (del)
{
//最多一个孩子
if (del->_left == NULL)
{
if (del == _root)
{
_root = del->_right;
}
else
{
if (del == parent->_left)
{
parent->_left = del->_right;
}
else
{
parent->_right = del->_right;
}
}
delete del;
del = NULL;
return true;
}
else if (del->_right == NULL)
{
if (del == _root)
{
_root = del->_left;
}
else
{
if (del == parent->_left)
{
parent->_left = del->_left;
}
else
{
parent->_right = del->_left;
}
}
delete del;
del = NULL;
return true;
}
//两个孩子
else
{
//找右子树的最左节点
parent = del;
BSTreeNode<K, V>* leftmost = del->_right;
while (leftmost->_left)
{
parent = leftmost;
leftmost = leftmost->_left;
}
//交换
swap(del->_key, leftmost->_key);
swap(del->_value, leftmost->_value);
if (leftmost == parent->_left)
{
parent->_left = leftmost->_right;
}
if (leftmost == parent->_right)
{
parent->_right = leftmost->_right;
}
delete leftmost;
leftmost = NULL;
return true;
}
}
return false;
}
bool Remove_R(const K& key)
{
return _Remove(_root, key);
}
BSTreeNode<K, V>* Find_NR(const K& key)
{
while (_root)
{
if (key > _root->_key)
{
_root = _root->_right;
}
else if (key < _root->_key)
{
_root = _root->_left;
}
else
{
return _root;
}
}
return NULL;
}
BSTreeNode<K, V>* Find_R(const K& key)
{
return _Find(_root, key);
}
void InOrder()
{
_InOrder(_root);
}
protected:
bool _Insert(BSTreeNode<K, V>* root, const K& key, const V& value)
{
if (root != NULL)
{
if (key > root->_key)
{
_Insert(root->_right, key, value);
if (root->_right==NULL)
{
root->_right = new BSTreeNode<K, V>(key, value);
return true;
}
}
else if (key < root->_key)
{
_Insert(root->_left, key, value);
if (root->_left==NULL)
{
root->_left = new BSTreeNode<K, V>(key, value);
return true;
}
}
else if (key == root->_key)
{
return false;
}
}
}
bool _Remove(BSTreeNode<K, V>*& root, const K& key)
{
if (NULL == root)
{
return false;
}
if (key > root->_key)
{
return _Remove(root->_right, key);
}
else if (key < root->_key)
{
return _Remove(root->_left, key);
}
else
{
BSTreeNode<K, V>* del = root;
if (root->_left == NULL)
{
root = root->_right; //root是引用
delete del;
}
else if (root->_right == NULL)
{
root = root->_left;
delete del;
}
else
{
BSTreeNode<K, V>* leftmost = root->_right;
while (leftmost->_left)
{
leftmost = leftmost->_left;
}
swap(del->_key, leftmost->_key);
swap(del->_value, leftmost->_value);
return _Remove(root->_right, key);
}
}
}
BSTreeNode<K, V>* _Find(BSTreeNode<K, V>* root, const K& key)
{
if (NULL == root)
{
return false;
}
if (key > root->_key)
{
_Find(root->_right, key);
}
else if (key < root->_key)
{
_Find(root->_left, key);
}
else
{
return root;
}
}
void _InOrder(BSTreeNode<K, V>* root)
{
if (NULL == root)
{
return;
}
_InOrder(root->_left);
cout << root->_key << "->" << root->_value << endl;
_InOrder(root->_right);
}
protected:
BSTreeNode<K, V>* _root;
};