数据结构-二叉树

二叉树的概述

二叉树是编写程序中使用的一种基本的数据存储结构,因为它通常结合了有序数组和链表的特点,在树中查找数据项的速度快,并且插入数据项和删除数据项也快

二叉树的规则

二叉树中的节点最多只能有两个子节点,分别称为"左子节点"和"右子节点",二叉树中的节点不是必须有2个子节点,它可以只有一个左或者右子节点,或者干脆没有子节点,没有子节点的节点我们称为叶子节点
在这里插入图片描述
注意:
二叉树的定义中,一个节点的左子节点的关键字值小于这个父节点,右子节点的关键字值大于或等于这个父节点 例如上图根节点(12) 左边的节点都是小于12,右边的节点都是大于等于12

树的查找

在这里插入图片描述
查找步骤:

  • 和根节点12比较,小于根节点,取左子节点10进行比较
  • 和节点10进行比较,比节点大,取10的右子节点进行比较
  • 和节点11进行比较,值相等返回查找结果

树的效率

查找节点的时间取决于这个节点所在的层数,如上图有7个节点的树有3层,最大比较次数为3,所以可以总结出树的层数与节点数量的关系为2的L次方减1
公式: N=2^L-1 N为树节点数量,L为层数
例如: 上图7个节点,3层 7=2^3-1
根据公式可以大概计算出,从20亿数据中查找一个数字时,需要比较31次,相比与无序数组或链表效率高很多。
因此,树的操作时间复杂度大致为N以2为底的对数。在大O表示法中,表示为O(logN)

插入一个节点

要插入一个节点,必须先找到插入的地方,从根节点开始查找一个相应的节点,它将是新节点的父节点。当父节点找到了,新的节点就可以连接到它的左子节点或右子节点,这取决于新节点的值是比父节点的值大还是小。如下图,我们插入一个新节点24:
在这里插入图片描述
插入步骤:

  • 和根节点12比较,大于根节点,取右子节点20进行比较
  • 和20比较,大于20节点,取右子节点25比较
  • 和20比较,小于25,25没有左子节点,把24当作25的左子节点插入

删除一个节点

删除节点是二叉树常用的一般操作中最复杂的,但是,删除节点在很多树的应用中又非常的重要,所以可以给出两种方法逻辑删除和物理删除,逻辑删除没有什么好说的就是在节点中给一个属性标记这个节点是否正常使用,下面我们来说说物理删除:
删除节点要从查找节点开始,找到节点后需要考虑三种情况:

  • 该节点是叶子节点
  • 该节点有一个子节点
  • 该节点有两个子节点
一、删除没有子节点的节点

要删除叶子节点,只需要改变该节点的父节点的对应字段的值,把指向该节点的字段改为null就可以。当叶子节点没有引用时,利用java的垃圾自动回收机制进行回收(注意:红色节点)
在这里插入图片描述
删除24这个节点步骤

  • 找到24这个节点
  • 将23这个节点的左子节点属性修改为null,leftChile=null
二、删除有一个子节点的节点

第二种情况也不是很难,这个节点只有两个连接:连向父节点的和连向它唯一的子节点的。把它的子节点直接连接到它的父节点上,这个过程要求改变父节点的引用。如下图(注意:红色节点,为我们要删除的节点)
在这里插入图片描述

三、删除有两个子节点的节点

如果要删除的节点有两个子节点,就不能只是用它的一个子节点代替它。如下图(注意:红色节点,为我们要删除的节点)
在这里插入图片描述
如果我们要删除12这个节点,并且用它的右子节点20去替代,那么20的左子节点18又该放到哪里呢?
在二叉树中的节点时按照升序的关键字值排列的,对每个节点来说,比该节点的关键字值次高的节点是它的中序后继,可以简称为该节点的后继,如上图18就是节点12的后继,删除有两个子节点的节点,就是用它的中序后继来代替该节点
例如:
在这里插入图片描述
其实说白了就是在大于等于12中找一个最小的来做后继节点
当然举一反三我们也可以第一步向左走一步,之后全部向右找到最后一个右子节点如上图的节点11,也可以作为后继节点,这个就刚好和之前的相反是在比12小的节点中找出最大的
操作步骤

  • 找到要删除的节点
  • 找到要删除节点的右节点
  • 顺着这个右节点的所有左子节点路径向下找,直到没有左子节点的节点
  • 将后继节点挪动到删除节点的位置

遍历树

遍历树的意思是根据一种特定顺序访问树的每一个节点,这个过程不如查找、插入、删除节点常用,因为便利树的速度不是特别快
有三种单的便利方法

  • 前序遍历:先打印根节点,然后打印它的左子树,最后打印它的右子树
  • 中序遍历:先打印它的左子树,然后打印根节点,最后打印它的右子树
  • 后序遍历:先打印它的左子树,然后打印它的右子树,最后打印根节点
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值