定义:
二叉搜索树
又称二叉排序树,它或者是一棵空树
,或者是具有以下性质的二叉树
:
若它的左子树不为空,则左子树上所有节点的值都小于根节点的值
若它的右子树不为空,则右子树上所有节点的值都大于根节点的值
它的左右子树也分别为二叉搜索树
![](https://i-blog.csdnimg.cn/blog_migrate/d5c97f81d01f79d57d575f6e1a4cf459.png)
二叉搜索树的
中序遍历是单调递增的:
![](https://i-blog.csdnimg.cn/blog_migrate/95c09ba2d6d4c708bf51082c6d514c5f.png)
二叉搜索树---搜索节点
从树根出发,逐步地缩小查找范围,直到发现目标(成功)或缩小至空树(失败)
在上树中搜索22的过程如下:
首先,经与根节点 16比较确认目标关键 码更大,故深入右子树 25递归查找;经比较发 现目标关键码更小,故 继续深入左子树19递 归查找;经再次比较确 认目标关键码更大后, 深入右子树22递归查 找;最终在节点22处匹 配,查找成功。
如果搜索到空还没有找到,则查找失败。
二叉搜索树---插入节点
1.树为空,则直接插入
2.树不为空,按二叉搜索树性质查找插入位置,插入新节点,查找插入位置的思想和搜索节点类似
二叉搜索树---删除节点
首先查找元素是否在二叉搜索树中,如果不存在,则返回
若存在,要删除的结点可能分下面几种情况
1.若要删除叶节点,直接删除
2.若要删除的节点只有左子树或右子树,删除该节点,并用子树代替空出的位置
3.若要删除的节点左右子树都存在,找到该节点的直接后继节点(中序遍历的下一个,即右子树的值最小的节点),交换两节点的值,删除目标节点(
因为是右树最小值,故无左孩子),其子树替代方法
同1和2
C++实现二叉搜索树:
#include<iostream>
using namespace std;
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:
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 < cur->_key)
parent->_right = cur;
else
parent->_left = cur;
return true;
}
Node* Find(const K& key)
{
Node* cur = _root;
while (cur)
{
if (key > cur->_key)
cur = cur - > right;
else if (key < cur->_key)
cur = cur->left;
else
return cur;
}
return nullptr;
}
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 == parent->_left)
parent->_left = cur->_right;
else
parent->_right = cur->_right;
delete cur;
return true;
}
else if (cur->_right == nullptr)
{
if (cur == parent->_left)
parent->_left = cur->_left;
else
parent->_right = cur->_left;
delete cur;
return true;
}
else
{
Node* next = cur->_right;
Node* pnext = cur;
while (next->_left)
{
pnext = next;
next = next->_left;
}
cur->_key = next->_key;
if (next == pnext->_left)
pnext->_left = next->_right;
else
pnext->_right = next->_right;
delete next;
return true;
}
}
}
return false;
}
void InOrder()
{
_InOrder(_root);
cout << endl;
}
private:
void _InOrder(Node* root)
{
if (root == nullptr)
{
return;
}
_InOrder(root->_left);
cout << root->_key << " ";
_InOrder(root->_right);
}
private:
Node* _root = nullptr;
};
int main()
{
int a[] = { 5, 3, 4, 1, 7, 8, 2, 6, 0, 9 };
BSTree<int> t;
for (auto e : a)
{
t.Insert(e);
}
t.InOrder();
t.Erase(7);
t.InOrder();
t.Erase(5);
t.InOrder();
return 0;
}
测试结果:
( 本文图示部分参自《数据结构》邓俊辉 )