三行代码递归实现二叉树层序遍历

三行代码递归实现二叉树层序遍历简述二叉树的层序遍历网上大部分都是使用队列的出队和入队来实现的,这次我用三行代码递归实现二叉树的层序遍历.层序下图是一个简单的二叉树,层序就是一行一行的往下读取,这个二叉树的层序结果便是:1234567(图画的比较丑,强迫症看着难受,看官忍一下)递归分析要想使用递归,必须有两个条件:函数参数类型相同递归必须有出口在二叉树中找到上面的两个条件,与

大家好,又见面了,我是你们的朋友全栈君。

简述

二叉树的层序遍历网上大部分都是使用队列的出队和入队来实现的,这次我用三行代码递归实现二叉树的层序遍历.

层序

下图是一个简单的二叉树,层序就是一行一行的往下读取,这个二叉树的层序结果便是:
1234567

这里写图片描述
(图画的比较丑,强迫症看着难受,看官忍一下)

递归分析

要想使用递归,必须有两个条件:

  1. 函数参数类型相同
  2. 递归必须有出口

在二叉树中找到上面的两个条件,与前中后三种遍历一样,函数参数为节点的,递归出口是当左右孩子为空的时候.传入根节点,然后依次递归访问左右孩子,直至为空.

重点

那么问题来了,递归遍历的数据保存到那?如何做到保存后是层序的顺序?

继续观察这张图
这里写图片描述

第一层
根节点标记为1元素是层序输出的第一个值
第二层
标记为2的元素是层序输出的第二个值,同时他是标记为1节点的左孩子
标记为3的元素是层序输出的第三个元素,同时他是标记为1的节点的右孩子.
第三层
标记为4的元素是输出的第四个元素,他是标记为2节点的左孩子
标记为5的元素是输出的第五个元素,他是标记为2节点的右孩子

很容易找到一个规律:

  • 每一个节点左孩子在层序中输出的位置是该节点在层序输出位置的二倍
  • 每一个节点右孩子在层序中输出的位置是该节点在层序输出位置的二倍加一
  • 根节点在层序输出的位置为1

    也就是:
    假设当前节点输出的位置是i,那么他的左孩子层序输出的位置是2*i,他的右孩子在层序输出的位置为2*i+1

代码实现

根据上面得出的结论,就可以写出层序遍历的递归代码了,知道了节点层序输出的位置,那么遍历时候直接保存到指定位置,等所有节点遍历结束后再统一输出,这个与前中后遍历是不一样的.
既然是根据位置去保存,那么当然是使用数组了,位置就是数组的下标,根据下标进行存放,操作非常方便.

这一段代码,是把字符二叉树层序遍历

int tree2str(bitree *b,char *a,int i)
{
    if(b->left!=NULL)
    {
        tree2str(b->left,a,2*i);
    }
    if(b->right!=NULL)
    {
        tree2str(b->right,a,2*i+1);
    }
    *(a+i)=b->data;
}

注意
参数a为数组的首地址,调用时候传递参数i初始值为1,代表第一层,既就是根界点,当递归函数执行完毕时候,所有的元素都在对应的位置,a[0]元素始终为空,因为是从1开始存放的,所以调用之后输出的时候应该从a+1的位置开始,字符串结束应该是’\0’,输出前补上防错.
这里写图片描述
(本人测试环境:系统Ubuntu16.04LTS 编译器GCC5.4,字符串末尾没有添加’\0’未出错,在vc6.0会出现烫烫烫烫烫烫烫烫烫……)

结束

回到最初,标题说是三行代码,实际上为了看的方便在if函数后面加了花括号,我觉得一行代码的标志应该是一个分号,既一个语句;所以上面的也算是三行代码了.

如果上面的不算三行代码,那就看下面

int tree2str(bitree *b,char *a,int i)
{
    if(b->left!=NULL)       tree2str(b->left,a,2*i);
    if(b->right!=NULL)      tree2str(b->right,a,2*i+1);
    *(a+i)=b->data;
}

好了现在很直观的三行了[完].

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/143300.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Android错误之ListView加载错位_ListView图片错位

    又遇到ListView加载item时,多个item中的图片会错位的情况现象如下图,同一个人的头像显示的乱七八糟找了一张图,很好地说明了问题的原因问题原因就在于convertView的重用,当重用 convertView 时,最初一屏显示 7 条记录, getView 被调用 7 次,创建了 7 个 convertView,当 Item1 划出屏幕, Item8 进入屏幕时,这时没有为 Item8

    2022年3月11日
    46
  • hibernate实现多租户[通俗易懂]

    hibernate实现多租户[通俗易懂]hibernate实现多租户

    2022年4月25日
    42
  • 打开jupter notebook报错[WinError 10049]「建议收藏」

    打开jupter notebook报错[WinError 10049]「建议收藏」首先从anaconda下打开jupyternotebook,报错如下:File“F:\anaconda\Scripts\jupyter-notebook-script.py”,line10,insys.exit(main())File“F:\anaconda\lib\site-packages\jupyter_core\application.py”,line268,inlaunch_instancereturnsuper(JupyterApp,cls).launch_i

    2022年10月1日
    3
  • 不同网段实现全网互通的方式_同一网段无法互通

    不同网段实现全网互通的方式_同一网段无法互通实现不同网段vlan互访【实验拓扑】【实验过程】一.二层设备依据拓扑创建vlan,实现同vlan互访。1.sw1创建vlan100、vlan200.2.将接口加入相应的vlan。验证:二、实现跨交换机相同vlan互访。1.sw1、sw2开启trunk,并允许vlan通过。创建vlan100、vlan200,并将接口加入对应的vlan。验证是否跨交换机相同vlan可以互访。三、配置单臂路由。实现不同vlan可以互访。1.配置子接口,充当vlan100

    2025年11月1日
    2
  • 什么是分区容错性?[通俗易懂]

    什么是分区容错性?[通俗易懂]这个回答我觉得一个知乎上的老哥说的特别好,我把他的话引用过来。原回答地址:https://www.zhihu.com/question/54105974一个分布式系统里面,节点组成的网络本来应该是连通的。然而可能因为一些故障,使得有些节点之间不连通了,整个网络就分成了几块区域。数据就散布在了这些不连通的区域中。这就叫分区。当你一个数据项只在一个节点中保存,那么分区出现后,和这个节点不连通的部分就访问不到这个数据了。这时分区就是无法容忍的。提高分区容忍性的办法就是一个数据项复制到多个节点.

    2022年7月25日
    13
  • JAVA集合Set之HashSet详解

    HashSet这个类实现了Set集合,实际为一个HashMap的实例。并且HashSet提供了三个构造函数

    2022年4月4日
    123

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号