问题描述:

给你一个二叉树,请你返回其按 层序遍历 得到的节点值。 (即逐层地,从左到右访问所有节点)。

示例:
二叉树:[3,9,20,null,null,15,7]

返回其层次遍历结果:

[
[3],
[9,20],
[15,7]
]
通过

来源:力扣(LeetCode)
二叉树的层序遍历

目录

1.非递归用循环队列
2.递归实现层次遍历

在栈与队列:匹配问题都是栈的强项中提到,「递归的实现就是:每一次递归调用都会把函数的局部变量、参数值和返回地址等压入调用栈中」,然后递归返回的时候,从栈顶弹出上一次递归的各项参数,所以这就是递归为什么可以返回上一层位置的原因。

知识前提:循环队列,二叉树的基本运算

非递归用循环队列

//思路
进行层次遍历时构建一个辅助队列,先将二叉树根节点入队,然后出队,访问出队结点,若它有左子树,将左子树根节点入队,然后出队,访问出队结点…,右子树也同样如此,循环往复直到队列为空

1.构建好辅助队列Q和二叉树T;
2.首先将二叉树的T(根节点)入队列;
3.进入while循环,退出条件 :队列为空;
4.循环内部:首先将队列中的队首元素出栈,并且输出他的值;
若队首元素(刚刚出队的元素)有左子树,将其左子树入队
若队首元素(刚刚出队的元素)有右子树,将其右子树入队
详细代码(可直接运行)

补充:如何让输出为一层一行

方法说起来很简单,只要仔细想,应该都能想出这种方法来。

定义两个变量curLevelCount和nextLevelCount来分别保存当前层和下一层的结点数。

显然,curLevelCount的初始值为1,因为只有一个根结点,而nextLevelCount由于未知,故置为0.

思路:
1.输出一行一行的与之前输出为一行的代码大体相似
2.构建好辅助队列Q和二叉树T;
3.再定义两个变量:curLevelCount用于记录当前层次结点个数,nextLevelCount用于记录当前层次的下一层结点的个数
4.将二叉树的根节点入栈,同时curLevelCount=1,nextLevelCount=0;
5.进入while循环,退出条件 :队列为空;
6.循环内部:首先将队列中的队首元素出栈,并且输出他的值;(与此同时,将curLevelCount–);
若队首元素(刚刚出队的元素)有左子树,将其左子树入队.(与此同时,将nextLevelCount++);
若队首元素(刚刚出队的元素)有右子树,将其右子树入队.(与此同时,将nextLevelCount++);
若curLevelCount减到零:输出一个换行符,将nextLevelCount赋值给curLevelCount,
nextLevelCount=0;

代码:非递归用循环队列

#include<stdio.h>typedef int Status;
#define TRUE  1
#define FALSE 0
#define  ERROR 0
#define  OK 1
#include<malloc.h>
#include<stdlib.h>
#include<stdio.h>
#include<bits/stdc++.h> typedef char TElemType;
typedef int status;
typedef struct BiNode
{TElemType data;struct BiNode *lchild;struct BiNode *rchild;
}BiNode,*BiTree;
typedef BiTree ElemType;
typedef BiTree QElemType;
//----------循环队列 --顺序存储结构-----------------------
#define  MAXQSIZE  100    // 最大队列长度+1
typedef  struct {ElemType   *base;   // 初始化的动态分配存储空间int   front;    // 头指针,若队列不空,指向队列头元素int   rear;   // 尾指针,若队列不空,指向队列尾元素的下一个位置
}  SqQueue;
void InitQueue(SqQueue &Q)
{    // 构造一个空队列QQ.base = (QElemType *)malloc(MAXQSIZE * sizeof(QElemType));if(!Q.base) // 存储分配失败exit(0);Q.front = Q.rear = 0;
}
void DestroyQueue(SqQueue &Q)
{   // 销毁队列Q,Q不再存在if(Q.base)free(Q.base);Q.base = NULL;Q.front = Q.rear = 0;
}
int QueueLength(SqQueue &Q)
{return ((Q.rear-Q.front+MAXQSIZE)%MAXQSIZE);
}
Status EnQueue(SqQueue &Q, QElemType e)
{   // 插入元素e为Q的新的队尾元素if((Q.rear + 1) % MAXQSIZE == Q.front) // 队列满return ERROR;Q.base[Q.rear] = e;Q.rear = (Q.rear + 1) % MAXQSIZE;return OK;
}
Status DeQueue(SqQueue &Q, QElemType &e)
{  // 若队列不空,则删除Q的队头元素,用e返回其值,// 并返回OK;否则返回ERRORif(Q.front == Q.rear) // 队列空return ERROR;e = Q.base[Q.front];Q.front = (Q.front + 1) % MAXQSIZE;return OK;
}
Status GetHead(SqQueue Q, QElemType &e)
{   // 若队列不空,则用e返回Q的队头元素,并返回OK;// 否则返回ERRORif(Q.front == Q.rear) // 队列空return ERROR;e = Q.base[Q.front];return OK;
}
Status QueueEmpty(SqQueue Q)
{// 若队列Q为空队列,则返回TRUE;否则返回FALSEif(Q.front == Q.rear) // 队列空的标志return TRUE;elsereturn FALSE;
}
void traverse(SqQueue &Q)
{int x;x=Q.front;int num=QueueLength(Q);for(int i=0;i<num;i++){printf("%d--",Q.base[(x++)%MAXQSIZE]);}
}void CreateBiTree(BiTree &T)//二叉树的先序创建
{TElemType ch;scanf("%c",&ch);if(ch=='#')T=NULL;else {T=(BiNode*)malloc(sizeof(BiNode));if(!T)exit(-1);T->data=ch;CreateBiTree(T->lchild);CreateBiTree(T->rchild);}
}void DestroyBiTree(BiTree &T)//二叉树的销毁算法
{if(T==NULL)exit(-1);else{DestroyBiTree(T->lchild);DestroyBiTree(T->rchild);free(T);}
}int  preorderTraverse(BiTree T)//二叉树的先序递归遍历算法
{if(T==NULL)return 0;else {printf("%c ",T->data);preorderTraverse(T->lchild);preorderTraverse(T->rchild);}} int  InorderTraverse(BiTree T)//二叉树的中序递归遍历算法
{if(T==NULL)return 0;else {InorderTraverse(T->lchild);printf("%c ",T->data);InorderTraverse(T->rchild);}}int  PostorderTraverse(BiTree T)//二叉树的后序递归遍历算法
{if(T==NULL)return 0;else {PostorderTraverse(T->lchild);PostorderTraverse(T->rchild);printf("%c ",T->data);}}void BiTree_level_traversal1(BiTree T)//按层输出一行
{SqQueue Q;InitQueue(Q);EnQueue(Q,T);BiTree temp;while(!QueueEmpty(Q)){DeQueue(Q, temp);printf("%c ",temp->data);if(temp->lchild!=NULL)EnQueue(Q,temp->lchild);if(temp->rchild!=NULL)EnQueue(Q,temp->rchild);}} void BiTree_level_traversal(BiTree T)// 层次遍历输入一层一层的
{SqQueue Q;InitQueue(Q);EnQueue(Q,T);BiTree temp;int curLevelCount=1,nextLevelCount=0; while(!QueueEmpty(Q)){DeQueue(Q, temp);printf("%c ",temp->data);curLevelCount--;if(temp->lchild!=NULL){EnQueue(Q,temp->lchild);nextLevelCount++;}if(temp->rchild!=NULL){EnQueue(Q,temp->rchild);nextLevelCount++;}if(curLevelCount==0){printf("\n"); curLevelCount = nextLevelCount;nextLevelCount=0;}}} int main()
{BiTree T;printf("创建树输入树T的先序序列(其中使用#代表空节点)\n");CreateBiTree(T);printf("先序遍历算法");preorderTraverse(T);printf("\n中序遍历算法");InorderTraverse(T);printf("\n后序遍历算法");PostorderTraverse(T);printf("\n遍历结果为:\n");BiTree_level_traversal1(T);printf("\n一层一层的输出\n"); BiTree_level_traversal(T);
}

递归实现层次遍历

思路:
1.先利用BiTree_height1(BiTree T)求二叉树高度算法,求得高度
2.levelOrder( BiTree T)层次遍历递归算法(这个函数仅一个for循环),用for()将二叉树一层一层的输出,每一层输出完,再输出一个换行符。
3.printNodeAtLevel(BiTree T,int level)(真正的递归遍历输出函数)
若level==0,输入此时的T->data;


int BiTree_height1(BiTree T)//求树的深度算法1
{if(T==NULL)return 0;else{if(BiTree_height1(T->lchild)>BiTree_height1(T->rchild))return 1+BiTree_height1(T->lchild);elsereturn 1+BiTree_height1(T->rchild);}}
void printNodeAtLevel(BiTree T,int level)
{  if(T==NULL||level<0)  return;  if(level==0)  {  printf("%c ",T->data);return;  }  // 左子树的 level - 1 级  printNodeAtLevel(T->lchild,level-1);  // 右子树的 level - 1 级  printNodeAtLevel(T->rchild,level-1);
}void levelOrder(const BiTree T)
{if(T==NULL)return;int totalLevel = BiTree_height1(T);for(int i = 0; i< totalLevel; i++){printNodeAtLevel(T, i);printf("\n");//打印完一层,换行}
}

代码:递归实现(全部代码)

#include<stdio.h>
#include<bits/stdc++.h> typedef char TElemType;
typedef int status;
typedef struct BiNode
{TElemType data;struct BiNode *lchild;struct BiNode *rchild;
}BiNode,*BiTree;
void CreateBiTree(BiTree &T)//二叉树的先序创建
{TElemType ch;scanf("%c",&ch);if(ch=='#')T=NULL;else {T=(BiNode*)malloc(sizeof(BiNode));if(!T)exit(-1);T->data=ch;CreateBiTree(T->lchild);CreateBiTree(T->rchild);}
}void DestroyBiTree(BiTree &T)//二叉树的销毁算法
{if(T==NULL)exit(-1);else{DestroyBiTree(T->lchild);DestroyBiTree(T->rchild);free(T);}
}int  preorderTraverse(BiTree T)//二叉树的先序递归遍历算法
{if(T==NULL)return 0;else {printf("%c ",T->data);preorderTraverse(T->lchild);preorderTraverse(T->rchild);}} int  InorderTraverse(BiTree T)//二叉树的中序递归遍历算法
{if(T==NULL)return 0;else {InorderTraverse(T->lchild);printf("%c ",T->data);InorderTraverse(T->rchild);}}int  PostorderTraverse(BiTree T)//二叉树的后序递归遍历算法
{if(T==NULL)return 0;else {PostorderTraverse(T->lchild);PostorderTraverse(T->rchild);printf("%c ",T->data);}}int BiTree_height1(BiTree T)//求树的深度算法1
{if(T==NULL)return 0;else{if(BiTree_height1(T->lchild)>BiTree_height1(T->rchild))return 1+BiTree_height1(T->lchild);elsereturn 1+BiTree_height1(T->rchild);}}
void printNodeAtLevel(BiTree T,int level)
{  if(T==NULL||level<0)  return;  if(level==0)  {  printf("%c ",T->data);return;  }  // 左子树的 level - 1 级  printNodeAtLevel(T->lchild,level-1);  // 右子树的 level - 1 级  printNodeAtLevel(T->rchild,level-1);
}void levelOrder(const BiTree T)
{if(T==NULL)return;int totalLevel = BiTree_height1(T);for(int i = 0; i< totalLevel; i++){printNodeAtLevel(T, i);printf("\n");//打印完一层,换行}
} int main()
{BiTree T;printf("创建树输入树T的先序序列(其中使用#代表空节点)\n");CreateBiTree(T);printf("先序遍历算法");preorderTraverse(T);printf("\n中序遍历算法");InorderTraverse(T);printf("\n后序遍历算法");PostorderTraverse(T);printf("\n二叉树层次遍历算法\n");levelOrder(T);}

数据结构——二叉树的层次遍历相关推荐

  1. 数据结构——二叉树的层次遍历进阶

    之前的一个博客 数据结构--二叉树的层次遍历看完这个,可以简单实现下面的问题 问题: 1.计算二叉树的最大宽度(二叉树的最大宽度是指二叉树所有层中结点个数的最大值. 2.用按层次顺序遍历二叉树的方法, ...

  2. 6-5 二叉树的层次遍历 (6分)_数据结构实验5_羊卓的杨

    6-5 二叉树的层次遍历 (6分) 本题要求实现给定的二叉树的层次遍历. 函数接口定义: void Levelorder(BiTree T); T是二叉树树根指针,Levelorder函数输出给定二叉 ...

  3. 数据结构——二叉树的递归遍历算法与非递归遍历算法+层次遍历算法

    (文章篇幅有点长,二叉树的递归遍历算法不作详细分析,但是二叉树的非递归遍历算法和层次遍历算法都有非常详细的分析过程,记得往下翻哦!) 二叉树的递归遍历算法实现 我们首先用递归的方法先序遍历创建这样一棵 ...

  4. leetcode-102 二叉树的层次遍历

    给定一个二叉树,返回其按层次遍历的节点值. (即逐层地,从左到右访问所有节点). 例如: 给定二叉树: [3,9,20,null,null,15,7] 3 / \ 9 20 / \ 15 7 返回其层 ...

  5. c++根据二叉树的层次遍历建立二叉树_LeetCode | 102.二叉树的层次遍历

    这次来写一下 LeetCode 的第 102 题,二叉树的层次遍历. 题目描述 题目直接从 LeetCode 上截图过来,题目如下: 102.二叉树的层次遍历题目 上面的题就是 二叉树的层次遍历 题目 ...

  6. 二叉树的层次遍历_【腾讯面试热身题】二叉树层次遍历(动画展示)

    二叉树的层次遍历同时涉及到树和队列两种数据结构的操作,因此大厂很喜欢用来作为面试的热身题.作者不少去腾讯的小伙伴,都反映,这种题一定要非常熟练,不然会被直接pass. 1 题目描述 给定一个二叉树,按 ...

  7. 二叉树层次遍历c语言_每日一道 LeetCode (23):二叉树的层次遍历 II

    ❝ 每天 3 分钟,走上算法的逆袭之路. ❞ 前文合集 每日一道 LeetCode 前文合集 代码仓库 GitHub:https://github.com/meteor1993/LeetCode Gi ...

  8. 按层次遍历二叉树_LeetCode | 102.二叉树的层次遍历

    这次来写一下 LeetCode 的第 102 题,二叉树的层次遍历. 题目描述 题目直接从 LeetCode 上截图过来,题目如下: 上面的题就是 二叉树的层次遍历 题目的截图,同时 LeetCode ...

  9. 关于二叉树的层次遍历的花样(c++实现)

    花样变形1::二叉树层次遍历但是分层打印 分析:与普通打印多了一个分层打印,其实只要在在层次遍历中多设置一个标记变量即可 代码如下: //二叉树的层次遍历 void levelTravel(BTNod ...

最新文章

  1. 一步一步写自己的SqlHelper类库
  2. 圣诞日记2010-12-25:认清形势,看清方向,正确选择,努力拼搏(更新 )
  3. Semantic Web 文章目录
  4. 1个平方大概多少立杆_1斤草坪种子播撒多少平方/四季青
  5. 在职测试多年整理了自己常用的Linux命令...
  6. CentOS 6.5设置静态IP教程 并且可以ping通
  7. SaltStack 学习笔记 - 第十二篇: SaltStack Web 界面
  8. c 语言 时空权衡的计数排序程序,算法设计和分析部分算法伪代码.doc
  9. win10 更新计算机时间,win10下如何更改系统更新时间和更新方式?win10设置系统更新时间和更新方式的技巧...
  10. jenkins pipeline分目录检出多代码库方法
  11. Springboot测试类之@RunWith注解
  12. 第二章—v-directive自定义指令
  13. 【转】C++多继承的细节
  14. 带特殊符号|的字符串的截取
  15. Haproxy启动故障:Starting proxy:cannot bind socke
  16. 给20块钱买可乐,每瓶可乐3块钱,喝完之后退瓶子可以换回1块钱,问最多可以喝到多少瓶可乐。
  17. 例1.1-2 Strongbox
  18. web_制作一个用户名 密码 性别 兴趣爱好 注册的界面
  19. 大数据时代之2013
  20. 没有公网ip怎么外网访问nas?快解析内网端口映射到公网

热门文章

  1. 使用VS Code 从零开始开发并调试.NET Core 应用程序
  2. 电机与系统计算机仿真作业,北邮计算机仿真期末大作业.docx
  3. Landsat中国西北地区行列号Shapefile图层对照(附行列号Shapefile下载)
  4. 【三维激光扫描】实验01:环境搭建CAD2014+StonexSiScan软件安装
  5. 【遥感物候】Matlab求解一元六次多项式,计算植被生长季始期
  6. 古董来了:1999年的物件,香港已经回归了,我都上初中了,那么你出生了吗?
  7. C语言试题七之将函数字符串中的前导*号全部删除,中间和尾部的*号不删除。
  8. 趣学算法之哥德巴赫猜想的实现
  9. linux之网络编程ICMP校验算法
  10. python 新建html_Python学习第226课——html中创建按钮