目录
二叉搜索树的概念
1.结点定义
2.构造、析构、拷贝构造、赋值重载
3.插入、删除、查找、排序
3.1插入
3.2插入递归版
3.3查找指定值
3.3查找指定值递归版
3.4中序遍历
3.5删除
最后
二叉搜索树的概念
二叉搜索树又称为二叉排序树或二叉查找树,它或者是一棵空树,或者是具有以下性质的二叉树:
- 非空左子树上所有结点的值都小于根结点的值。
- 非空右子树上所有结点的值都大于根结点的值。
- 左右子树都是二叉搜索树。
1.结点定义
template<class K>
struct BSTreeNode
{
BSTreeNode<K>* _left;
BSTreeNode<K>* _right;
K _key;
BSTreeNode(const K& key)
:_key(key)
,_left(nullptr)
,_right(nullptr)
{}
};
2.构造、析构、拷贝构造、赋值重载
//构造函数
BSTree()
: _root(nullptr)
{
}
//析构函数
~BSTree()
{
//递归删除
Destroy(_root);
_root = nullptr;
}
//拷贝构造
BSTree(const BSTree<K>& t)
{
//递归去拷贝
_root = Copy(t._root);
}
//赋值重载
BSTree<K>& operator=(BSTree<K> t)//注意这里传参,传值传参,默认已经拷贝构造新的一份了
{
swap(_root, t._root);//这里直接交换return 就好
return *this;
}
Node* Copy(Node* root)
{
//前序遍历
if (root == nullptr)
{
return nullptr;
}
Node* newRoot = new Node(root->_key);
//建立联系,不是简单的调用
newRoot->_left = Copy(root->_left);
newRoot->_right = Copy(root->_right);
return newRoot;
}
void Destroy(Node* root)
{
if (root == nullptr)
{
return;
}
Destroy(_root->_left);
Destroy(_root->_right);
delete(root);
}
3.插入、删除、查找、排序
3.1插入
bool Insert(const K& key)
{
//不允许相等数据插入版本,减少冗余
//空树
if (_root == nullptr)
{
_root = new Node(key);
return true;
}
//正常插入
Node* cur = _root;
Node* parent = _root;
while (cur != nullptr)
{
if (key > cur->_key)
{
parent = cur;
cur = cur->_right;
}
else if (key < cur->_key)
{
parent = cur;
cur = cur->_left;
}
else
{
return false;
}
}
cur = new Node(key);
if (key > parent->_key)
{
parent->_right = cur;
}
else
{
parent->_left = cur;
}
return true;
}
3.2插入递归版
bool InsertR(const K& key)//注意参数
{
return _InsertR(_root, key);
}
bool _InsertR(Node* &root,const K& key)
{
if (root == nullptr)
{
root = new Node(key);
return true;
}
if (root->_key > key)
{
return _InsertR(root->_left, key);
}
else if (root->_key < key)
{
return _InsertR(root->_right, key);
}
else
{
//相等
return false;
}
}
3.3查找指定值
bool Find(const K& key)
{
Node* cur = _root;
while (cur!=nullptr)
{
if (cur->_key > key)
{
cur = cur->_left;
}
else if (cur->_key < key)
{
cur = cur->_right;
}
else
{
return true;
}
}
return false;
}
3.3查找指定值递归版
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 true;
}
if (root->_key > key)
{
return _FindR(root->_left, key);
}
else
{
return _FindR(root->_right, key);
}
}
3.4中序遍历
void InOrder()
{
_InOrder(_root);
}
void _InOrder(Node* root)
{
if (root == nullptr)
{
return;
}
_InOrder(root->_left);
cout << root->_key << " ";
_InOrder(root->_right);
}
3.5删除
bool Erase(const K& key)
{
Node* cur = _root;
Node* parent = _root;
while (cur)
{
//找到节点
if (cur->_key > key)
{
parent = cur;
cur = cur->_left;
}
else if (cur->_key < key)
{
parent = cur;
cur = cur->_right;
}
else
{
//找到了
//删除没有孩子或者只有一种孩子的节点
//这个是普通节点
if (cur->_right == nullptr)
{
if (parent->_left == cur)
{
parent->_left = cur->_left;
}
if (parent->_right == cur)
{
parent->_right = cur->_left;
}
if(parent==cur)//是根结点
{
parent = parent->_left;
}
delete(cur);
return true;
}
else if(cur->_left==nullptr)
{
if (parent->_left == cur)
{
parent->_left = cur->_right;
}
if (parent->_right == cur)
{
parent->_right = cur->_right;
}
if (parent == cur)//是根结点
{
parent = parent->_right;
}
delete(cur);
return true;
}
else
{
//左右都不为空
//替换法删除,找右子树的最小值
Node* miniright = cur->_right;
Node* minirightp = cur;
while (miniright->_left != nullptr)
{
minirightp = miniright;
miniright = miniright->_left;
}
cur->_key = miniright->_key;
if (minirightp->_left == miniright)
{
minirightp->_left = miniright->_right;
}
if (minirightp->_right == miniright)
{
minirightp->_right = miniright->_right;
}
delete(miniright);
return true;
}
}
}
return false;
}
最后
加油