开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第11天,点击查看活动详情
二叉搜索树
二叉搜索树又称二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树:
若它的左子树不为空,则左子树上所有节点的值都小于根节点的值
若它的右子树不为空,则右子树上所有节点的值都大于根节点的值
它的左右子树也分别为二叉搜索树
二叉搜索树实现 非递归插入|非递归查找
#include<iostream>
using namespace std;
template<class K>
class BStreeNode
{
public:
BStreeNode(const K& key)
:_left(nullptr),
_right(nullptr),
_key(key)
{}
BStreeNode<K>* _left;
BStreeNode<K>* _right;
K _key;
};
template<class K>
class BStree
{
typedef BStreeNode<K> Node;
public:
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 true;
}
void InOrder()
{
_InOrder(_root);
}
private:
void _InOrder(Node *root)
{
if (root == nullptr)
return;
_InOrder(root->_left);
cout << root->_key << " ";
_InOrder(root->_right);
}
private:
Node* _root = nullptr;
};
int main()
{
BStree<int> t;
int a[] = { 1,1,2,2,3,6,165,132,4185,123 };
for (auto e : a)
{
t.Insert(e);
}
t.InOrder();
return 0;
}
非递归删除代码
bool Erase(const K& key)//删除
{
//若有一个子节点,删除父节点后,让子节点填充
//若有俩个子节点,父节点删除后
//1.用左子树的最大节点替换父节点
//2.或右子树的最小节点替换父节点
Node* parent = nullptr;
Node* cur = _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->_left == nullptr)//如果要删除的节点左为空
{
if (cur == _root)//如果要删除的是根节点(这种情况根节点只有右子树,因为左为空)
{
_root = cur->_right;
}
else
{
if (cur == parent->_left)//判断要删除的节点是父亲的左节点还是右节点
{
parent->_left = cur->_right;
}
else
{
parent->_right = cur->_right;
}
}
delete cur;
cur = nullptr;
}
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;
}
}
delete cur;
cur = nullptr;
}
else//左右都为空,叶子节点,这里采用用右树的最小节点进行删除
{
Node* minParent = cur;
Node*min = cur->_right;//cur是要删除的节点
while (min->_left)//寻找最小节点
{
minParent = min;
min = min->_left;
}
swap(cur->_key, min->_key);
if (minParent->_left == min)
{
minParent->_left = min->_right;
}
else
minParent->_right = min->_right;
delete min;
}
return true;
}
}
return false;
}