Android 二叉树理解

二叉树的性质

如果有2个子节点,那么左侧的比它本身的值小,右侧的比它本身的值大

  • 查找:

查找过程:

        19小于33,则查找子左节点:17;

        19大于17,则查找子右节点18;

        因为19大于18,则继续找子右节点25;

        因为19小于25,则查找左节点19;

        等于了,说明我们找到了;

  • 插入

  插入过程:

        55大于33,则往子右节点查找,即50;

        55大于50,则继续往子右节点查找,即58;

        55小于58,则往子左节点查找;即51;

        发现51无子节点,则,直接将55插入子节点的位置;因为55是大于51的,所以插入子右节点位置;

  • 删除节点

删除过程:

删除13:

先查找:

        13小于33,则继续查找子左节点,即16;

        13小于16,则继续查找子左节点,即13;

        我们看到13只有1个子节点15,则直接删除13,将15直接添加到13的位置; 

        如果要删除的节点只有一个子节点,我们只需要更新父节点中指向要删除节点的指针,让它指向要删除节点的子节点就可以了

删除18:

先查找

        18小于33,则继续查找子左节点,即16;

        18大于16,则继续查找子右节点,即18;

        因为18有2个子节点,并且子树节点的最小值为19,则直接把19放到删除的18位置上,其他节点不变;

        如果要删除的节点有两个子节点,这时我们需要找到这个节点的右子树中的最小节点,把它替换到要删除的节点上,然后再删除这个最小节点

删除55:

        55大于33,则继续查找子右节点,即50;

        55大于50,则继续查找子右节点,即58;

        55小于58,则继续查找子左节点,即51;

        55大于51,则查找子右节点,即55;

        因为55没有子节点,则直接删除置为null即可;

        如果要删除的节点没有子节点,我们只需要直接将父节点中指向要删除节点的指针置为null

总结:如果要删除的节点没有子节点,我们只需要直接将父节点中指向要删除节点的指针置为null。比如删除图中的节点55。
如果要删除的节点只有一个子节点,我们只需要更新父节点中指向要删除节点的指针,让它指向要删除节点的子节点就可以了。比如删除图中的节点13。
如果要删除的节点有两个子节点,这时我们需要找到这个节点的右子树中的最小节点,把它替换到要删除的节点上,然后再删除这个最小节点。比如删除图中的节点18。

  • 支持重复数据的二叉查找树

第一种方法比较容易。二叉查找树中每一个节点不仅仅存储一个数据,我们通过链表和支持动态扩容的数组等数据结构,把值相同的数据都存储在同一个节点上。
第二种方法是,每个节点仍然只存储一个数据。在查找插入位置的过程中,如果碰到一个节点与要插入数据的值相同,我们就将这个要插入的数据放到这个节点的右子树,即把这个新插入的数据当作大于这个节点的值来处理;
当要查找数据的时候,遇到值相同的节点,我们并不停止查找操作,而是继续在右子树中查找,直到遇到叶子节点,才停止,这样就可以把键值等于要查找值的所有节点都找出来。
 

遍历:

先序遍历:先访问根节点,然后访问左节点,最后访问右节点。

中序遍历:先访问左节点,然后访问根节点,最后访问右节点。

后序遍历:先访问左节点,然后访问右节点,最后访问根节点。

先序遍历、中序遍历、后序遍历,表示访问根节点的时机分别是最先,第二、最后;

public class Node {
    Object data;
    Node left = null;
    Node right = null;
    void Node(Object data,Node left,Node right){
        this.data = data;
        this.left = left;
        this.right = right;
    }
}


public class BinaryTree {
    // 先序遍历
    void preSearch(Node root){
        if (root != null){
            System.out.printf("%-4s",root.data);
            preSearch(root.left);
            preSearch(root.right);
        }
    }
    // 中序遍历
    void midSearch(Node root){
        if (root != null){
            midSearch(root.left);
            System.out.printf("%-4s",root.data);
            midSearch(root.right);
        }
    }
    // 后序遍历
    void bacSearch(Node root){
        if (root != null){
            bacSearch(root.left);
            bacSearch(root.right);
            System.out.printf("%-4s",root.data);
        }
    }
}



参考博文:

基本性质:https://blog.csdn.net/qq_43232545/article/details/104857698

排序:https://blog.csdn.net/qq_40727800/article/details/106976963

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jian11058

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值