关闭

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

标签: 二叉树层序递归
275人阅读 评论(2) 收藏 举报
分类:

简述

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

层序

下图是一个简单的二叉树,层序就是一行一行的往下读取,这个二叉树的层序结果便是:
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;
}

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

2
2
查看评论

数据结构之树和二叉树算法实现(C语言)

待我学有所成,结发与蕊可好。@夏瑾墨 开发环境为Dev-C++ 5.11 编译器:MinGW GCC 6.1.0 64-bit 一、算法程序组建目录结构如下: 第一部分:头文件 1. c1.h 2. c3-3.h 3. c6-1.h 4. c6-2.h 5. c6-3....
  • the_Sixth_String
  • the_Sixth_String
  • 2016-10-26 01:40
  • 2128

二叉树的层序遍历

二叉树的层序遍历就是按照二叉树的深度分层遍历,也就是广度优先遍历(BFS)。层序遍历使用队列,一种先进先出(FIFO)的数据结构。下面简单介绍下二叉树 的层序遍历。 层序遍历从根节点开始,将根节点压入队列中,每次访问一个节点,就将其左右儿子节点压入队列中,直到队列为空,说明遍历结束。代码如下: ...
  • u012877472
  • u012877472
  • 2015-10-27 17:13
  • 3822

二叉树的实现及四种常用遍历(python)

构造节点类 构造树类,并增加添加节点方法 前序遍历(根,左,右)、中序遍历(左,根,右),后序遍历(左,右,根) 利用队列实现广度优先遍历,即层次遍历 [引用]树的遍历主要有两种,一种是深度优先遍历,像前序、中序、后序;另一种是广度优先遍历,像层次遍历。在树结构中两者的区别还不是...
  • qq_29631251
  • qq_29631251
  • 2017-06-20 15:18
  • 360

二叉树的层序遍历(递归)

输出二叉树的层序遍历序列 如[2,6,8,null,null,10,12],输出[[2],[6,8],[10,12]] Binary Tree Level Order Traversal 借助vector/** * Definition for a binary tree node. * ...
  • Tao_Ba
  • Tao_Ba
  • 2016-11-08 22:44
  • 957

C语言二叉树的层序遍历

在上一篇中我记录了二叉树的先序,中序,后序的递归和非递归遍历方法,这一篇会接着上一篇的,记录二叉树的层序遍历方法,层序遍历用到了队列的数据结构,下面直接上代码: 1、首先是链队列的数据结构定义,LinkQueue.h文件: #pragma once #include "BinaryTree...
  • yubo_725
  • yubo_725
  • 2015-11-22 15:41
  • 4196

【数据结构与算法】二叉树的层序遍历

前面有篇博客详细分析了二叉树三种遍历(前序、中序、后序)方式的递归与非递归实现,参见:http://blog.csdn.net/ns_code/article/details/12977901,但把二叉树的层序遍历算法给漏掉了,实际上也不能说漏掉了,毕竟层序遍历的实现方法与这三种遍历的实现方法有所不...
  • mmc_maodun
  • mmc_maodun
  • 2013-10-27 14:51
  • 22008

层序遍历二叉树(不借助vector或deque,用C语言实现)

前面几篇文章中,我们对二叉树的层序遍历和层序打印都是借助vector或deque来实现的,本文只通过C语言来实现,代码如下:#include <iostream> using namespace std; #define MAXSIZE 1000typedef struct node {...
  • cyuyanenen
  • cyuyanenen
  • 2016-06-02 19:36
  • 1763

二叉树的层序遍历详细讲解(附完整C++程序)

1 说明   二叉树的层序遍历是面试经常会被考察的知识点,甚至要求当场写出实现过程。笔者先后被腾讯和滴滴面试官问过这个问题,腾讯面试官是让称述整个实现过程,本人自信满满的说出来了,所以也没有对具体实现太上心。等到滴滴面试的时候,让我详细写出实现,真正上手之后发现原理懂,但是如果没有朝一个正确的方向努...
  • FX677588
  • FX677588
  • 2017-07-03 22:23
  • 3731

队列实现二叉树层序遍历

//基本数据结构 template struct BinaryTreeNode { T _data; BinaryTreeNode* _left; BinaryTreeNode* _right; BinaryTreeNode(const T& x) :_data(x) ,_l...
  • xingchao_1995
  • xingchao_1995
  • 2017-03-30 19:21
  • 554

二叉树层序遍历

微软面试题,难度系数低,题目描述如下: 输入一颗二元树,从上往下按层打印树的每个结点,同一层中按照从左往右的顺序打印。  例如输入           8        ...
  • pediy_yuhan
  • pediy_yuhan
  • 2014-02-06 11:44
  • 2256
    个人资料
    • 访问:24610次
    • 积分:446
    • 等级:
    • 排名:千里之外
    • 原创:16篇
    • 转载:0篇
    • 译文:0篇
    • 评论:42条
    文章分类
    最新评论