二叉树的遍历 节点个数 第k层节点个数 查找 判断是否为完全二叉树

二叉树是数据结构中不仅可以用来存储数据的,同时也可以有很多其他的功能,比如说二叉搜索树,如果中序遍历的话就是排序加去重等,而且查找效率很高,如果是AVL树或者红黑树(二叉树的一种)查找效率为log n,效率特别高,所以二叉树很重要,但是普通的二叉树没有什么用,所以这里不会教你如何push或者pop等,这里只能教你如何编辑等,但是这里很重要的是一种思想(递归),下面会讲清楚的

那么下面先看一下二叉树的节点

38e684f16c0944d8b9afebe758819ca2.png

 OK就是这样,其实这个结构和链表没什么区别,由于是二叉树所以需要两个指针,一个左 一个右

下面我们就先看一下二叉树如何遍历

其中二叉树的遍历方法有很多种,有前中后序遍历,其中这三个都是用递归(用循环也可以,不过这里用递归更简单一点,以后会说到循环的),还有一个是层序遍历,其中这个直接用循环,一会会说到思路的

今天就只看一下遍历等简单的

所以我们先看一下前序遍历

9fbead62d88740fcb8142687d0cdcd56.png

 假设我们要遍历这棵树,那么前序遍历怎么遍历呢?

这里首先应该说一下什么是前序遍历,首先遍历就是对这棵树挨个走一遍,不一定要打印,如果这里我们遍历就是打印出来,那么前序遍历就是,我们先打印根节点,在打印左孩子节点,在打印右孩子节点,所以我们来看一下这棵树

5575c2cf3c9f4b7597144e1f536eb67d.png

这里我们只画了一小部分,和我一起看一下,首先我们的第一个节点是4,那么4是我们的根节点,所以我们直接打印,然后根节点访问完之后我们就要去他的左孩子节点2,然后打印,那么此时2就是我们的根节点,根节点访问完之后我们还是得去他的左孩子节点1然后我们打印1,这时候我们同样把1看作我们的根节点,此时我们需要访问1的左孩子节点,但是1的左孩子节点为空,所以我们直接返回即可,然后此时1这个根节点访问玩了,1的左孩子节点也访问完了,那么就要去1的右孩子节点,同样为空直接返回,然后我们就把1这一整棵树都访问完了,所以我们就已经访问完了2的左子树,2的左子树访问完之后,我们就需要去访问2的右子树,和刚才同样的步骤,此时我们2这棵树也访问完了,所以我们4这棵树的根节点访问完了,同时4的左子树也访问完了,所以我们就需要访问4的右子树,和上面步骤相同,都是(根 左 右)先访问根,在访问左子树,在访问右子树就是这样,那么这棵树前序遍历是怎么样子的,我们先看一下他遍历出来是什么样子

fc7990af459c4e65aeda21a074f62b96.png 

这就是前序遍历出来后的效果,下面我们就来看一下代码怎么实现

32fc8f35d5c54966908ffaca382f9370.png 

我们说了,前中后序遍历是用递归,而这里递归,我们可以看一下,首先我们 可以看一下,我们先把根节点传给该函数,然后他直接去打印根节点,然后再递归调用自己,把左孩子和右孩子分别传给该函数

这里还是可以画一下递归展开图

13e0d1e46cb04b5c9b83322d17534ed8.png

我们可以看到,我们先把4传进去,然后他不是空所以会调用他自己,然后把他的左孩子传进去

2fd3b00630bb421ab1bb9dd6ba5d07f4.png 

就是这样,虽然这里画的不是很好,但是可以将就看懂,这里就是先把4传进去,然后打印,4又不为空,所以把他的左孩子穿进去,2又不为空,然后打印,又访问2的左孩子,为1然后打印,把传进去,由于1的左为空所以直接返回,此时传入1左孩子的这一个函数已经调用结束了,所以需要把1的右孩子传进去,然后也为空返回,此时前序遍历1这棵树已经访问结束,又返回到上一层,就是这样下去

前序遍历就是这样,下面看一下中序遍历和后序遍历,其实和前序遍历一样,只是访问根节点的时机不同,下面就不详细讲解了

a4ae6c35f3de451bb34e2e0cd536c28d.png 

首先这里是中序遍历,中序遍历就是左 根 右,那么先是4这个节点, 首先能不能访问4这个节点?不能因为访问根之前先要访问根的左

c0809102fdd94ff4a23ffc198d8bad1f.png

所以应该先访问4的左,那么就是2,此时可不可以访问2,还是不可以,因为先要访问2的左就是1,和上面一样能不能访问1,不可以因为先要访问1的左,由于1的左是空,所以我们直接返回就可以,这时候1的左已经访问结束,这时候才可以访问1这个节点

b02c98dfb29d44099afcb2e2b824f887.png 

此时已经把1访问了,那么就要访问1的右,由于1的右也为空,所以直接返回,此时1这棵树就访问结束了,所以要访问2了

 30084601127743db803dfc1a57555d72.png

就是这样,和之前的步骤相同,所以这棵树中序遍历结束后就是这样

f2ee435868734278979dde0efcfb149d.png 

下面我们就看代码,这次不画递归展开图了,可以自己去画,按照上面的逻辑

直接看代码

7767cf5c7f214885ad8484abac64fdb8.png 

下面就看后序遍历,同时也是访问实际不同,就是先访问左,在访问右,最后访问根,这里也就直接看代码,和前面都是一样的,也可以自己画一下递归展开图,这样思路会更清晰一点

7b406e7acddb465895df1b21a017ae65.png 

本来准备讲层序遍历和其他几个的,但是现在时间有点不够,所以只能在这里了,剩下的下一节讲 。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Naxx Crazy

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

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

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

打赏作者

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

抵扣说明:

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

余额充值