今天分享关于二叉搜索树的实现。
二叉搜索树BinarySearchTree(或者SearchBinaryTree),是一种特殊的二叉树,这个树的所有节点满足对于所有的根节点它的左孩子比它小,右孩子比它大。
主要实现了它的插入(递归和非递归方法),查找(查找一个节点是否在BSTree中),删除(递归和非递归方法)
删除是重点
删除节点分为3种情况:
1 节点左为空
2 节点右为空
3 节点左右都不为空 需要找到替换节点来代替这个删除的节点从而保证二叉搜索树的特性。
代码如下:
//二叉搜索树 根节点小于左右节点,左节点小于右节点 二叉树的建立,有递归方法和非递归法 注意递归方法的函数参数,操作的是根节点所以要用引用。
#include <iostream>
#include <assert.h>
using namespace std;
template<class K>
struct BSTreeNode
{
BSTreeNode<K>* _left;
BSTreeNode<K>* _right;
K _key;
BSTreeNode(const K& key)
:_key(key)
, _right(NULL)
, _left(NULL)
{}
};
template<class K>
class BinarySearchTree
{
typedef BSTreeNode<K> Node;
public:
BinarySearchTree()
:_root(NULL)
{}
bool Insert(const K& key)
{
if (_root == NULL)
{
_root = new Node(key);
return true;
}
else
{
Node* parent = NULL;
Node* cur = _root;
while (1)
{
parent = cur;
if (cur->_key < key)//比当前节点大,往右边插入
{
cur = cur->_right;
if (cur == NULL)//当前节点为空,有位置插入了
{
parent->_right = new Node(key);
return true;
}
}
else if (cur->_key > key)//往左走
{
cur = cur->_left;
if (cur == NULL)
{
parent->_left = new Node(key);
return true;
}
}
else if (cur->_key = key)//搜索二叉树一般不会插入重复的key值
{
return false;
}
}
}
}
bool RemoveR(const K& key)
{
return _RemoveR(_root, key);
}
bool InSertR(const K& key)//递归插入
{
return _InSertR(_root, key);
}
const Node* Find(const K& key)
{
if (_root == NULL)
{
return NULL;
}
Node* cur = _root;
while (cur)
{
if (cur->_key == key)
{
return cur;
}
if (cur->_key > key)
{
cur = cur->_left;
}
if (cur->_key < key)
{
cur = cur->_right;
}
}
return NULL;
}
bool FindR(const K& key)
{
return _FindR(_root, key);
}
bool Remove(const K& key)
{
if (_root == NULL)
{
return false;
}
Node* cur = _root;
Node* parent = cur;
while (cur)
{
if (cur->_key > key)
{
parent = cur;
cur = cur->_left;
}
else if (cur->_key < key)
{
parent = cur;
cur = cur->_right;
}
else if (cur->_key == key)//找到了这个节点,删除节点
{
if (cur->_right == NULL)//当前节点右为空
{
if (cur == parent->_left)
{
parent->_left = cur->_left;
delete cur;
return true;
}
else if (cur == parent->_right)
{
parent->_right = cur->_left;
delete cur;
return true;
}
}
else if (cur->_left == NULL)
{
if (cur == parent->_left)
{
parent = cur->_right;
delete cur;
return true;
}
else if (cur == parent->_right)
{
parent->_right = cur->_right;
delete cur;
return true;
}
}
else if (cur->_left && cur->_right)//左右都不为空,替换法
{
Node* parent = cur;
Node* left = cur->_right;
while (left->_left)
{
parent = left;
left = left->_left;
}
cur->_key = left->_key;
if (left == parent->_left)
{
parent->_left = left->_right;
}
else
{
parent->_right = left->_right;
}
delete left;
return true;
}
}
}
return false;
}
void InOrder()
{
_InOrder(_root);
cout << endl;
}
protected:
bool _InSertR(Node*& root, const K& key)//插入要修改这个树所以参数传递Node*&
{
if (root == NULL)
{
root = new Node(key);//为空创建节点
return true;
}
if (root->_key > key)
{
return _InSertR(root->_left, key);//插入的数比当前节点key值小,往左走
}
else if (root->_key < key)
{
return _InSertR(root->_right, key);
}
else
{
return false;//已经有这个节点 返回false
}
}
bool _FindR(Node* root, const K& key)
{
if (root == NULL)
{
return false;
}
if (root->_key > key)
{
return _FindR(root->_left, key);
}
else if (root->_key < key)
{
return _FindR(root->_right, key);
}
else
{
return true;
}
}
bool _RemoveR(Node*& root, const K& key)
{
Node* cur = root;
Node* parent = cur;
if (cur == NULL)
{
return false;
}
if (cur->_key > key)
{
return _RemoveR(cur->_left, key);
}
else if (cur->_key < key)
{
return _RemoveR(cur->_right, key);
}
else
{
Node*del = cur;
if (root->_left == NULL)
{
root = root->_right;
}
else if (root->_right == NULL)
{
root = root->_left;
}
else
{
Node* parent = cur;
Node* left = cur->_right;
while (left->_left)
{
parent = left;
left = left->_left;
}
cur->_key = left->_key;
del = left;
if (left == parent->_left)
{
parent->_left = left->_right;
}
else
{
parent->_right = left->_right;
}
delete del;
return true;
}
}
}
Node* _InOrder(Node* root)
{
Node* cur = root;
if (cur == NULL)
{
return NULL;
}
else
{
_InOrder(root->_left);
cout << root->_key << " ";
_InOrder(root->_right);
}
return root;
}
Node* _root;
};