局部变量和传引用问题
#pragma once
namespace xiong
{
template<class K, class V>
struct TreeNode
{
K _key;
V _val;
TreeNode<K, V>* _left;
TreeNode<K, V>* _right;
TreeNode(const K& key, const V& val)
:_key(key)
,_val(val)
,_left(nullptr)
,_right(nullptr)
{}
};
template<class K, class V>
class BSTree
{
typedef TreeNode<K, V> Node;
public:
bool Insert(const K& key, const V& val)
{
Node* node = new Node(key, val);
if (_root == nullptr)
{
_root = node;
return true;
}
Node* cur = _root;
Node* prev = nullptr;
while (cur)
{
prev = cur;
if (key < cur->_key)
{
cur = cur->_left;
}
else if (key > cur->_key)
{
cur = cur->_right;
}
else
return false;
}
//因为cur这里时局部变量,无法直接修改,所以要判断上一结点指向
//链接,区分左右结点
if (key < prev->_key)
prev->_left = node;
if (key > prev->_key)
prev->_right = node;
return true;
}
查找
//bool Find(const K& key)
//{
// Node* cur = _root;
// while (cur)
// {
// if (key < cur->_key)
// {
// cur = cur->_left;
// }
// else if (key > cur->_key)
// {
// cur = cur->_right;
// }
// else
// return true;
// }
// return false;
//}
Node* Find(const K& key)
{
Node* cur = _root;
while (cur)
{
if (key < cur->_key)
{
cur = cur->_left;
}
else if (key > cur->_key)
{
cur = cur->_right;
}
else
return cur;
}
return nullptr;
}
//删除结点
bool Erase(const K& key)
{
if (!Find(key))
return false;
Node* cur = _root;
Node* prev = nullptr;
while (cur)
{
if (key < cur->_key)
{
prev = cur;
cur = cur->_left;
}
else if (key > cur->_key)
{
prev = cur;
cur = cur->_right;
}
else
{
//删除结点左为空
if (cur->_left == nullptr)
{
//结点为树的根结点
if (cur == _root)
{
_root = cur->_right;
}
else
{
//链接
if (prev->_right == cur)
{
prev->_right = cur->_right;
}
else
{
prev->_left = cur->_right;
}
}
delete cur;
}
//删除结点右为空
else if (cur->_right == nullptr)
{
//结点为树的根结点
if (cur == _root)
{
_root = cur->_left;
}
else
{
//链接
if (prev->_right == cur)
{
prev->_right = cur->_left;
}
else
{
prev->_left = cur->_left;
}
}
delete cur;
}
//删除结点左右均不为空
else
{
//找左子树最大结点,替换要删除的结点
Node* leftmax = cur->_left;
prev = cur;
while (leftmax->_right)
{
prev = leftmax;
leftmax = leftmax->_right;
}
cur->_key = leftmax->_key;
//链接
if (prev->_left == leftmax)
{
prev->_left = leftmax->_left;
}
if (prev->_right == leftmax)
{
prev->_right = leftmax->_left;
}
delete leftmax;
}
return true;
}
}
return false;
}
//中序遍历
void Inorder()
{
_Inorder(_root);
cout << endl;
}
//递归插入
bool InsertR(const K& key)
{
return _InsertR(_root, key);
}
//递归删除
bool EraseR(const K& key)
{
return _EraseR(_root, key);
}
//递归查找
bool FindR(const K& key)
{
return _FindR(_root, key);
}
private:
bool _InsertR(Node*& root, const K& key)
{
if (root == nullptr)
{
//因为这里加了一层_InsertR 函数,为传引用传参,
//故可以直接修改root不用判断左右
root = new Node(key);
return true;
}
if (key < root->_key)
return _InsertR(root->_left, key);
else if (key > root->_key)
return _InsertR(root->_right, key);
else
return false;
}
bool _EraseR(Node*& root, const K& key)
{
if (root == nullptr)
return false;
if (key < root->_key)
return _EraseR(root->_left, key);
else if (key > root->_key)
return _EraseR(root->_right, key);
else
{
if (root->_left == nullptr)
{
root = root->_right;
}
else if (root->_right == nullptr)
{
root = root->_left;
}
else
{
Node* leftmax = root->_left;
while (leftmax->_right)
{
leftmax = leftmax->_right;
}
swap(root->_key, leftmax->_key);
//这里的leftmax是临时变量,如果直接传leftmax
//修改递归内的root没有实际效果,所以只能传root->left
//return _EraseR(leftmax, key);
return _EraseR(root->_left, key);
}
return true;
}
}
bool _FindR(Node*& root, const K& key)
{
if (root == nullptr)
return false;
if (root->_key == key)
{
return true;
}
return _FindR(root->_left, key) || _FindR(root->_right, key);
}
void _Inorder(Node* root)
{
if (root == nullptr)
return;
_Inorder(root->_left);
cout << root->_key << ":" << root->_val << endl;
_Inorder(root->_right);
return;
}
Node* _root = nullptr;
};
}