【C++】二叉搜索树(上)

简介: 【C++】二叉搜索树

二叉搜索树的查找规则


3490be5de1dd4ad680bb93398c61c64d.png

从根开始比较,查找,比根大则往右边走查找,比根小则往左边走查找。

最多查找高度次,走到到空,还没找到,这个值不存在

二叉搜索树(二叉排序树)性质

非空左子树的所有值小于根节点的值

非空右子树的所有值大于根节点的值

左右子树都是二叉搜索树

0af7fa6570134c07a777249060f1fa96.png


第一个不满足,因为值为5的节点在值为10的节点的右边,正常来说10的右边都应该比10大

二叉搜索树的中序遍历

62e43d70ccb6471a819c9375a81a6d2f.png


遍历,一定可以得到一个递增的序列 中序为:1 3 4 6 7 8 10 13 14

二叉搜索树的实现 (非递归)

插入

分为两种情况

若插入的值在二叉树中不存在,则通过比较进行插入

1a8275f641054f17a740ae542c3e550e.png若插入11,因为11比8大,所以跟10比较,而11比10大,所以走10的右子树14,14与11比较,因14>11,所以走14的左子树13,11与13比较,因13>11,故作为13的左子树,遇见NULL指针停止

若插入的值,在二叉树中存在


636f00d768e64684ab30146b4180ee06.png

因为插入值13与二叉树中的值13相等,则直接返回false


5d88c816523442239087851c385903ca.png


实际上创建节点后,需要与二叉搜索树进行连接,去当前创建节点的上一个节点parent,

通过判断cur节点是parent节点左子树还是右子树 进行连接


bool Insert(const K& key)
    {
        if (_root = nullptr)//若root根节点为nullptr
        {
            _root = new Node(key);
            return true;
        }
        Node* cur = _root;
        Node* parent = NULL;//用于接收cur之前的节点
        while (cur != NULL)
        {
            if (cur->_key > key)//若插入的值比cur值小
            {
                parent = cur;
                cur = cur->_left;
            }
            else if (cur->_key < key)//若插入的值比cur值大
            {
                parent = cur;
                cur = cur->_right;
            }
            else//若相等,则直接返回false
            {
                return false;
            }
        }
        //遇见空指针,连接新节点
        //由于不知道parent的左还是右连接key,所以需要判断
        cur = new Node(key);
        if (parent->_key > key)
        {
            parent->_left = cur;
        }
        else
        {
            parent->_right = cur;
        }
        return true;
    }

中序遍历

inorder需要传根,但是由于_root是类的私有成员变量,所以没办法从.c文件传过来


5bd13f2e7a944833af1f858e62feb869.png

若将inorder函数设为缺省值,不可以通过编译

缺省值必须是常量或者全局变量,而root不是全局变量/常量 ,所以不能用缺省值

访问成员变量需要用this指针,而此时_root并没有this指针去指向

53edded49b4b497a8900d1db1fc77482.png

所以采用嵌套一层函数的方式,这样调用inorder函数时,不用传参数过来也可以解决问题

查找


bool Find(const K& key)
    {
        Node* cur = _root;
        while (cur != NULL)
        {
            if (cur->_key > key)
            {
                cur = cur->_left;
            }
            else if (cur->_key < key)
            {
                cur = cur->_right;
            }
            else
            {
                return true;
            }
        }
        return false;
    }

删除 (重点)

删除共分为三种情况

1. 要删除节点无孩子节点


712f26927ecb4dcaac8819ca2ced6839.png

删除4后,直接将6的左子树置为NULL


2.要删除节点只有左孩子节点/右孩子节点


1bae524f38b34d688a449a965b3ed54d.png

3.要删除节点有左孩子和右孩子节点


185b1e99bedf4a149a4c35f97f047a83.png

删除8节点,就需要寻找左子树的最大节点或者右子树最小节点 来当树的根节点

左子树的最大节点是最右节点

右子树的最小节点是最左节点

假设删除节点8,通过右子树的最小节点来进行替换,将右子树的最小节点替换掉cur节点值,删除右子树的最小节点即可


由于叶子节点的删除可以算为左为空/右为空的情况,所以只需考虑左为空/右为空 或者 删除节点有左孩子和右孩子节点 即可


左为空


187ef59fabc34772a7e919aa2d4a5768.png

左为空时,使用parent节点去接收cur的右子树,但是还需判断下cur的右子树节点在parent的左子树还是右子树

572ab88c0da542889f7f262e4d707b5b.png


需要考虑cur节点作为根的情况,此时的parent节点为NULL,NULL->right就会报错

8add7054fe2c4081ab604ec5ced47c89.png

为了解决这个问题,把cur的右子树的节点作为根,然后直接删除cur节点

4d393304b2bc4a909f506b82c5f4b931.png


相关文章
|
4月前
|
算法 测试技术 C++
【C++】map&set的底层结构 -- AVL树(高度平衡二叉搜索树)(下)
【C++】map&set的底层结构 -- AVL树(高度平衡二叉搜索树)(下)
|
4月前
|
C++ 容器
【C++】map&set的底层结构 -- AVL树(高度平衡二叉搜索树)(上)
【C++】map&set的底层结构 -- AVL树(高度平衡二叉搜索树)(上)
|
2月前
|
存储 C++
【C++】二叉树进阶之二叉搜索树(下)
【C++】二叉树进阶之二叉搜索树(下)
21 4
|
2月前
|
Java 编译器 C++
【C++】二叉树进阶之二叉搜索树(上)
【C++】二叉树进阶之二叉搜索树(上)
26 3
|
2月前
|
算法 测试技术 C++
【C++高阶】掌握AVL树:构建与维护平衡二叉搜索树的艺术
【C++高阶】掌握AVL树:构建与维护平衡二叉搜索树的艺术
24 2
|
3月前
|
存储 C++
【C++航海王:追寻罗杰的编程之路】一篇文章带你了解二叉搜索树
【C++航海王:追寻罗杰的编程之路】一篇文章带你了解二叉搜索树
30 1
|
3月前
|
C++
【c++】二叉搜索树
【c++】二叉搜索树
23 0
|
3月前
|
C++
【C++】学习笔记——二叉搜索树
【C++】学习笔记——二叉搜索树
20 0
|
4月前
|
存储 C语言 Python
从C语言到C++_24(二叉搜索树)概念+完整代码实现+笔试题(下)
从C语言到C++_24(二叉搜索树)概念+完整代码实现+笔试题
59 3
|
4月前
|
C语言
从C语言到C++_24(二叉搜索树)概念+完整代码实现+笔试题(中)
从C语言到C++_24(二叉搜索树)概念+完整代码实现+笔试题
31 1