概念:二叉搜索树又称二叉排序树,它是一颗空树或者是一颗具有以下特征的二叉树:
1.若它的左子树不为空,则它的左子树上所有的结点值都小于根节点的值。
2.若它的右子树不为空,则它的柚子树上所有的结点值都大于根节点的值。
3.它的左右子树也为二叉搜索树。
也就是如果是中序遍历的话,结果为有小到大的有序排列
二叉搜索树的几个基本功能:
1.插入
2.删除
3.查找
4.中序遍历
template<class K>
struct BSTreeNode
{
BSTreeNode<K>* _left;
BSTreeNode<K>* _right;
K _key;
BSTreeNode(const K& key)
:_left(nullptr)
,_right(nullptr)
,_key(key)
{}
};
这里我们准备了两个版本的插入实现:
非递归版的实现:
bool Insert(const K& key)//非递归版
{
if (_root == nullptr)
{
_root = new Node(key);
return true;
}
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
{
return false;
}
}
cur = new Node(key);
if (parent->_key < key)
{
parent->_right = cur;
}
else
{
parent->_left = cur;
}
return true;
}
递归版的实现:
bool Insert(const K & key)
{
return _Insert(_root, key);
}
bool _Insert(Node*& root, const K& key)
{
if (root == nullptr)
{
//这里是否有疑问为啥可以直接new一个新,不考虑链接吗
//原因在参数Node *& root,这里我们有一个引用,每次传递来的是对其区别名
root = new Node(key);
return true;
}
if (root->_key < key)
{
return _Insert(root->_right, key);
}
else if (root->_key > key)
{
return _Insert(root->_left, key);
}
else
{
return false;
}
}
这里也是提供两个版本的实现方式:
1.非递归的方式
bool Erase(const K & key)
{
Node* cur = _root;
Node* parent = nullptr;
while (cur)
{
//先找到要插入的地方
if (cur->_key > key)
{
parent = cur;
cur = cur->_left;
}
else if (cur->_key < key)
{
parent = cur;
cur = cur->_right;
}
else//找到了
{
//左右有一个为空,左为空
if (cur->_left == nullptr)
{
if (cur == _root)//cur为根时
{
_root = _root->_right;
}
else//不为空时,判断此时cur为parent的左还是右
{
if (parent->_left == cur)
{
parent->_left = cur->_right;
}
else
{
parent->_right = cur->_right;
}
}
}
//左右有一个为空,右为空
else if (cur->_right == nullptr)
{
if (cur == _root)//cur为根时
{
_root = _root->_left;
}
else//不为空时,判断此时cur为parent的左还是右
{
if (parent->_left == cur)
{
parent->_left = cur->_left;
}
else
{
parent->_right = cur->_left;
}
}
}
else //cur的左右两边都不为空时
{
//leftMax为替代节点
Node* leftMax = cur->_left;
parent = cur;//这里不能给空,如果leftMax直接找到,parent就无法找到了
while (leftMax->_right)//找到cur左边最大的那一个
{
parent = leftMax;
leftMax = leftMax->_right;
}
//找到后交换
swap(cur->_key, leftMax->_key);
//不要忽略链接的问题,也就是为啥要给parent cur的原因置空可能找不到parent
if (parent->_left == leftMax)
{
parent->_left = leftMax->_left;
}
else
{
parent->_right = leftMax->_left;
}
cur = leftMax;
}
delete cur;
return true;
}
}
return false;
}
2.递归版本:
bool Erase(const K& key)
{
return _Erase(_root, key);
}
bool _Erase(Node*& root,const K& key)
{
if (root == nullptr)
{
return false;
}
if (root->_key < key)
{
return _Erase(root->_right, key);
}
else if (root->_key > key)
{
return _Erase(root->_left, key);
}
else//找到了
{
Node* del = root;
// 1、左为空
if (root->_left == nullptr)
{
root = root->_right;
}
// 2、右为空
else if (root->_right == nullptr)
{
root = root->_left;
}
// 3、左右都不为空
else
{
//找到右边最大进行交换
Node* LeftMax = root->_left;
while (LeftMax->_right)
{
LeftMax = LeftMax->_right;
}
swap(root->_key, LeftMax->_key);
return _Erase(root->_left, key);//不能传leftmax,为局部变量
}
delete del;
return true;
}
}
bool FindR(const K & key)
{
return _FindR(_root, key);
}
bool _FindR(Node * root, const K & key)//
{
if (root == nullptr)
{
return false;
}
if (root->_key < key)
{
return _FindR(root->_right, key);
}
if (root->_key > key)
{
return _FindR(root->_left, key);
}
else
{
return true;
}
}
void InOrder()
{
_InOrder(_root);
cout << endl;
}
void _InOrder(Node * root)
{
if (root == NULL)
{
return;
}
_InOrder(root->_left);
cout << root->_key << " ";
_InOrder(root->_right);
}
最后我们来看:
#pragma once
template<class K>
struct BSTreeNode
{
BSTreeNode<K>* _left;
BSTreeNode<K>* _right;
K _key;
BSTreeNode(const K& key)
:_left(nullptr)
,_right(nullptr)
,_key(key)
{}
};
template<class K>
class BSTree
{
typedef BSTreeNode<K> Node;
public:
BSTree()
:_root(nullptr)
{}
BSTree(const BSTree<K>& t)
{
_root = copy(t._root);
}
~BSTree()
{
Destroy(_root);
}
BSTree<K>& operator=(BSTree<K> t)
{
swap(_root, t._root);
return *this;
}
/*bool Insert(const K& key)//非递归版
{
if (_root == nullptr)
{
_root = new Node(key);
return true;
}
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
{
return false;
}
}
cur = new Node(key);
if (parent->_key < key)
{
parent->_right = cur;
}
else
{
parent->_left = cur;
}
return true;
}*/
//bool 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 true;
// }
// }
// return false;
//}
//bool Erase(const K & key)
//{
// Node* cur = _root;
// Node* parent = nullptr;
// while (cur)
// {
// //先找到要插入的地方
// if (cur->_key > key)
// {
// parent = cur;
// cur = cur->_left;
// }
// else if (cur->_key < key)
// {
// parent = cur;
// cur = cur->_right;
// }
// else//找到了
// {
// //左右有一个为空,左为空
// if (cur->_left == nullptr)
// {
// if (cur == _root)//cur为根时
// {
// _root = _root->_right;
// }
// else//不为空时,判断此时cur为parent的左还是右
// {
// if (parent->_left == cur)
// {
// parent->_left = cur->_right;
// }
// else
// {
// parent->_right = cur->_right;
// }
// }
// }
// //左右有一个为空,右为空
// else if (cur->_right == nullptr)
// {
// if (cur == _root)//cur为根时
// {
// _root = _root->_left;
// }
// else//不为空时,判断此时cur为parent的左还是右
// {
// if (parent->_left == cur)
// {
// parent->_left = cur->_left;
// }
// else
// {
// parent->_right = cur->_left;
// }
// }
// }
// else //cur的左右两边都不为空时
// {
// //leftMax为替代节点
// Node* leftMax = cur->_left;
// parent = cur;//这里不能给空,如果leftMax直接找到,parent就无法找到了
// while (leftMax->_right)//找到cur左边最大的那一个
// {
// parent = leftMax;
// leftMax = leftMax->_right;
// }
// //找到后交换
// swap(cur->_key, leftMax->_key);
// //不要忽略链接的问题,也就是为啥要给parent cur的原因置空可能找不到parent
// if (parent->_left == leftMax)
// {
// parent->_left = leftMax->_left;
// }
// else
// {
// parent->_right = leftMax->_left;
// }
// cur = leftMax;
// }
// delete cur;
// return true;
// }
// }
// return false;
//}
//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
// {
// if (parent->_right == cur)
// {
// parent->_right = cur->_right;
// }
// else
// {
// parent->_left = cur->_right;
// }
// }
// }// 右为空
// else if (cur->_right == nullptr)
// {
// if (cur == _root)
// {
// _root = cur->_left;
// }
// else
// {
// if (parent->_right == cur)
// {
// parent->_right = cur->_left;
// }
// else
// {
// parent->_left = cur->_left;
// }
// }
// } // 左右都不为空
// else
// {
// // 找替代节点
// Node* parent = cur;
// Node* leftMax = cur->_left;
// while (leftMax->_right)
// {
// parent = leftMax;
// leftMax = leftMax->_right;
// }
// swap(cur->_key, leftMax->_key);
// if (parent->_left == leftMax)
// {
// parent->_left = leftMax->_left;
// }
// else
// {
// parent->_right = leftMax->_left;
// }
// cur = leftMax;
// }
// delete cur;
// return true;
// }
// }
// return false;
//}
void InOrder()
{
_InOrder(_root);
cout << endl;
}
bool FindR(const K & key)
{
return _FindR(_root, key);
}
bool Insert(const K & key)
{
return _Insert(_root, key);
}
bool Erase(const K& key)
{
return _Erase(_root, key);
}
private:
Node* copy(Node* root)
{
if (root == nullptr)
{
return nullptr;
}
Node* copyroot = new Node(root->_key);//
copyroot->_left = copy(root->_left);
copyroot->_right = copy(root->_right);
return copyroot;
}
void Destroy(Node*& root)
{
if (root == nullptr)
{
return;
}
Destroy(root->_left);
Destroy(root->_right);
delete root;
root = NULL;
}
bool _Erase(Node*& root,const K& key)
{
if (root == nullptr)
{
return false;
}
if (root->_key < key)
{
return _Erase(root->_right, key);
}
else if (root->_key > key)
{
return _Erase(root->_left, key);
}
else//找到了
{
Node* del = root;
// 1、左为空
if (root->_left == nullptr)
{
root = root->_right;
}
// 2、右为空
else if (root->_right == nullptr)
{
root = root->_left;
}
// 3、左右都不为空
else
{
//找到右边最大进行交换
Node* LeftMax = root->_left;
while (LeftMax->_right)
{
LeftMax = LeftMax->_right;
}
swap(root->_key, LeftMax->_key);
return _Erase(root->_left, key);//不能传leftmax,为局部变量
}
delete del;
return true;
}
}
bool _Insert(Node*& root, const K& key)
{
if (root == nullptr)
{
//这里是否有疑问为啥可以直接new一个新,不考虑链接吗
//原因在参数Node *& root,这里我们有一个引用,每次传递来的是对其区别名
root = new Node(key);
return true;
}
if (root->_key < key)
{
return _Insert(root->_right, key);
}
else if (root->_key > key)
{
return _Insert(root->_left, key);
}
else
{
return false;
}
}
bool _FindR(Node * root, const K & key)//
{
if (root == nullptr)
{
return false;
}
if (root->_key < key)
{
return _FindR(root->_right, key);
}
if (root->_key > key)
{
return _FindR(root->_left, key);
}
else
{
return true;
}
}
void _InOrder(Node * root)
{
if (root == NULL)
{
return;
}
_InOrder(root->_left);
cout << root->_key << " ";
_InOrder(root->_right);
}
Node* _root;
};
//简单的测试代码
void test()
{
int a[] = { 8, 3, 1, 10, 6, 4, 7, 14, 13 };
BSTree<int> t;
for (auto e : a)
{
t.Insert(e);
}
t.Erase(3);
t.Erase(10);
t.Erase(13);
BSTree<int> t1(t);
//t1 = t;
t.InOrder();
t1.InOrder();
}