数据结构——二叉树的层次遍历

问题描述:

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

示例:
二叉树:[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)
{
       // 构造一个空队列Q
    Q.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;否则返回ERROR
    if(Q.front == Q.rear) // 队列空
        return ERROR;
    e = Q.<
  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值