目录
1、二叉搜索树概念
2、 二叉搜索树的插入
3、二叉搜索树的查找
4、二叉搜索树的删除
5、二叉搜索树的中序遍历
实现
定义一个二叉搜索树类
template
struct BSTreeNode
{
BSTreeNode* _left;
BSTreeNode* _right;
K _key;
BSTreeNode(const K& key)
:_left(nullptr)
, _right(nullptr)
, _key(key)
{}
};
template
class BSTree
{
typedef BSTreeNode Node;
private:
Node* _root = nullptr;
public:
bool Insert(const K& key); //插入
bool Find(const K& key); //查找
bool Erase(const K& key); //删除
void InOrder(); //中序遍历
void _InOrder(Node* root);
};
template
bool BSTree::Insert(const K& key)
{
if (_root == nullptr)
{
_root = new Node(key);
return true;
}
Node* parent = nullptr;
Node* cur = _root;
while (cur != nullptr)
{
parent = cur;
if (cur->_key < key)
{
cur = cur->_right;
}
else if (cur->_key > key)
{
cur = cur->_left;
}
else
{
return false; //cur->_key == key
}
}
cur = new Node(key);
if (parent->_key < key)
{
parent->_right = cur;
}
else
{
parent->_left = cur;
}
return true;
}
template
bool BSTree::Find(const K& key)
{
Node* cur = _root;
while (cur != nullptr)
{
if (key < cur->_key) //key小于cur->_key,cur向左走
{
cur = cur->_left;
}
else if (key > cur->_key) //key大于于cur->_key,cur向右走
{
cur = cur->_right;
}
else //key等于于cur->_key,返回true
{
return true;
}
}
return false; //不存在返回false
}
替换法删除:我们可以使用被删的节点的左子树的最大节点或者右子树的最小节点,来替代被删的节点的值
template
bool BSTree::Erase(const K& key)
{
Node* parent = nullptr;
Node* cur = _root;
while (cur != nullptr)
{
if (cur->_key < key)
{
parent = cur;
cur = cur->_right;
}
else if (cur->_key > key)
{
parent = cur;
cur = cur->_left;
}
else //找到要删除的数
{
// 准备删除
//分为三种情况
//1、左为空
//2、右为空
//3、左右都不为空
if (cur->_left == nullptr) //左为空
{
if (cur == _root) //1、要删除的点为根节点
{
_root = cur->_right;
}
else
{
if (cur == parent->_left)
{
parent->_left = cur->_right;
}
else
{
parent->_right = cur->_right;
}
}
}
else if (cur->_right == nullptr) //右为空
{
if (cur == _root) //1、要删除的点为根节点
{
_root = cur->_left;
}
else
{
if (cur == parent->_left)
{
parent->_left = cur->_left;
}
else
{
parent->_right = cur->_left;
}
}
}
else //左右都不为空
{
//我们可以使用被删的节点的左子树的最大节点或者右子树的最小节点,
//来替代被删的节点的值
Node* parent = cur;
Node* subLeft = cur->_right;
while (subLeft->_left)
{
parent = subLeft;
subLeft = subLeft->_left; // 右子树的最小节点(最左节点)
}
swap(cur->_key, subLeft->_key); //右子树的最小节点与被删节点的值交换
if (subLeft == parent->_left)
{
parent->_left = subLeft->_right;
}
else
{
parent->_right = subLeft->_right;
}
}
return true;
}
}
return false; //没有找到要删除的数
}
根据二叉搜索树的特性,我们可以推出二叉搜索树的中序遍历是一个有序的数据
我们可以采用递归的方法去遍历
template
void BSTree::InOrder()
{
_InOrder(_root);
cout << endl;
}
template
void BSTree::_InOrder(Node* root)
{
if (root == nullptr)
return;
_InOrder(root->_left);
cout << root->_key << " ";
_InOrder(root->_right);
}
template
struct BSTreeNode
{
BSTreeNode* _left;
BSTreeNode* _right;
K _key;
BSTreeNode(const K& key)
:_left(nullptr)
, _right(nullptr)
, _key(key)
{}
};
template
class BSTree
{
typedef BSTreeNode Node;
private:
Node* _root = nullptr;
public:
bool Insert(const K& key); //插入
bool Find(const K& key); //查找
bool Erase(const K& key); //删除
void InOrder(); //中序遍历
void _InOrder(Node* root);
};
template
bool BSTree::Insert(const K& key)
{
if (_root == nullptr)
{
_root = new Node(key);
return true;
}
Node* parent = nullptr;
Node* cur = _root;
while (cur != nullptr)
{
parent = cur;
if (cur->_key < key)
{
cur = cur->_right;
}
else if (cur->_key > key)
{
cur = cur->_left;
}
else
{
return false; //cur->_key == key
}
}
cur = new Node(key);
if (parent->_key < key)
{
parent->_right = cur;
}
else
{
parent->_left = cur;
}
return true;
}
template
bool BSTree::Find(const K& key)
{
Node* cur = _root;
while (cur != nullptr)
{
if (key < cur->_key) //key小于cur->_key,cur向左走
{
cur = cur->_left;
}
else if (key > cur->_key) //key大于于cur->_key,cur向右走
{
cur = cur->_right;
}
else //key等于于cur->_key,返回true
{
return true;
}
}
return false; //不存在返回false
}
template
bool BSTree::Erase(const K& key)
{
Node* parent = nullptr;
Node* cur = _root;
while (cur != nullptr)
{
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 (cur == parent->_left)
{
parent->_left = cur->_right;
}
else
{
parent->_right = cur->_right;
}
}
}
else if (cur->_right == nullptr) //右为空
{
if (cur == _root)
{
_root = cur->_left;
}
else
{
if (cur == parent->_left)
{
parent->_left = cur->_left;
}
else
{
parent->_right = cur->_left;
}
}
}
else
{//左右都不为空
// 右树的最小节点(最左节点)
Node* parent = cur;
Node* subLeft = cur->_right;
while (subLeft->_left)
{
parent = subLeft;
subLeft = subLeft->_left;
}
swap(cur->_key, subLeft->_key);
if (subLeft == parent->_left)
parent->_left = subLeft->_right;
else
parent->_right = subLeft->_right;
}
return true;
}
}
return false;
}
template
void BSTree::InOrder()
{
_InOrder(_root);
cout << endl;
}
template
void BSTree::_InOrder(Node* root)
{
if (root == nullptr)
return;
_InOrder(root->_left);
cout << root->_key << " ";
_InOrder(root->_right);
}