在此之前,我们已经掌握了使用递归算法实现二叉树先序遍历、中序遍历和后序遍历的流程,这里我们加大一下难度,探讨该如何实现二叉树的层次遍历算法.

相信有朋友至此会直接回答"用递归算法解决". 我曾经也有过这种想法,可后来的实践证明,"用递归思想设计层次遍历算法"这种想法是不可行的:和之前提到的三种遍历过程不同的是,在二叉树的层次遍历过程中,对于各结点的操作并不能总结出共性,所以趁早打消"用递归思想解决层次遍历问题"的念头.

我们不着急设计算法,先在草稿本上画出一棵有代表性的二叉树,之后写出它的层次遍历序列.

写出遍历序列后,我们可以发现,遍历流程可以向下面这样进行归纳总结.

①根节点入队列,

②如果队列不空,跳转至③;否则结束循环.

③队头元素出队,

④访问出队元素结点的数据域,

⑤如果该结点有左孩子,那么左孩子结点入队; 如果该结点有右孩子,那么右孩子结点入队,

⑥跳转至②.

光有上面的思想显然是不够的,我们还需要考虑二叉树结点队列该如何搭建的问题.

这里为了节省队列的存储空间,将队列按照下述方式进行定义.

struct Queue//二叉树队列定义
{BiTreeNode* S[MAXSIZE];//指针数组, 数组中存放多个二叉树结点指针int Front;//队头"指针"int Rear;//队尾"指针"
}*Q;
void Init_Queue(Queue* &Q)//初始化队列
{Q=(Queue*)malloc(sizeof(Queue));Q->Front=Q->Rear=0;
}
void EnQueue(Queue* &Q, BiTreeNode* &T)//元素入队
{Q->S[Q->Rear]=T;Q->Rear=(Q->Rear+1)%MAXSIZE;
}
BiTreeNode* DeQueue(Queue* &Q)//元素出队
{BiTreeNode* T=Q->S[Q->Front];//保存当前队头元素Q->Front=(Q->Front+1)%MAXSIZE;return T;//将刚才保存的队头元素返回
}
bool QueueEmpty(Queue* &Q)//判断队列是否已空
{if(Q->Front==Q->Rear){return true;}else{return false;}
}
bool QueueFull(Queue* &Q)//判断队列是否已满
{if((Q->Rear+1)%MAXSIZE==Q->Front){return true;}else{return false;}
}

我相信有嗅觉敏锐的朋友会问道“只将某结点的指针存入队列,这样做可行吗”:其实我曾经也考虑过这个问题,但在实践过后得出结论"这样做是可行的".

俗话说的好, "人嘴两张皮,咋说咋随意",可不能仅靠我这一句"这样做是可行的"就认为这样是可行的了,我们需要做出进一步分析,再下结论.

我们先来看一下上面的队列定义过程. 我选用了顺序存储方式,并用一些简单的数学操作将队列变为"循环队列". 再来看一下队列元素进出队的本质: 某个二叉树结点元素进队<----等价---->队尾"指针"指向的单元指向该结点 + 队尾"指针"的值+1, 某个二叉树结点出队<----等价---->队头"指针"指向的二叉树结点的指针出队(temp负责记录出队指针) + 队头"指针"的值+1. 在整个队列的操作过程中,除队头元素和队尾元素外的中间元素是不允许修改的,所以"队列中直接存储二叉树结点的指针"这一方案是可行的.

既然这种方案已通过现阶段的论证,那么根据上面给出的层次遍历思想,即可设计出二叉树层次遍历的算法.

void LevelTraverse(BiTreeNode* &T)//层次遍历二叉树(※与队列相结合)
{BiTreeNode* temp;if(T==NULL)//如果main()函数传来的T指针为NULL{//说明所给二叉树的根结点指针为NULL//也即二叉树是空树//则直接返回main()函数return ;}EnQueue(Q,T);//将二叉树根节点入队列while(QueueEmpty(Q)==false)//只要队列不空, 就继续循环{temp=DeQueue(Q);//temp记录出队指针putchar(temp->data);//访问出队指针指向的二叉树结点cout<<" ";if(temp->LChild!=NULL)//如果存在左孩子{//左孩子指针进队列EnQueue(Q,temp->LChild);}if(temp->RChild!=NULL)//如果存在右孩子{//右孩子指针进队列EnQueue(Q,temp->RChild);}}
}

用队列作为辅助工具来解决二叉树的实际问题,可以说为数据结构的学习者打开了通往数据结构初级级别的一扇门. 在此算法前, 相信绝大多数朋友仅是停留在"能用C语言实现顺序表的各种操作"、"能用C语言实现顺序栈/顺序队列的基本操作"这一层级上,而未掌握跨章节解决问题的能力.

读者应仔细体会"算法结合队列进行实现"这一思维过程,以为日后设计更复杂的算法打下思维基础.

如何层次遍历二叉树(使用队列作为辅助工具)相关推荐

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

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

  2. 层次遍历二叉树(编程之美3.10)

    问题(假定根节点位于第0层) 1. 层次遍历二叉树(每层换行分开) 2. 层次遍历二叉树指定的某层 例如 上图中 1. 1 2 3 4 5 6 7 8 2. 第三层 7 8 可以看出得出第二问的解,第 ...

  3. 按层次遍历二叉树算法

    问题:按层次遍历二叉树 在网上看了一些按层次遍历二叉树的算法,这里修改了一下通过队列来按层次遍历二叉树的算法 --------------------------------------------- ...

  4. PTA - 按层次遍历二叉树

    按层次遍历二叉树 题目:以字符串的形式定义一棵二叉树的先序序列,若字符是'#', 表示该二叉树是空树,否则该字符是相应结点的数据元素.读入相应先序序列,建立二叉树,然后按层次遍历该二叉树并输出结点数据 ...

  5. c语言实现层次遍历二叉树完整代码

    //混用了一下c和c++(仅输入输出混用了一下,其他没有)#include<stdio.h> #include<stdlib.h> #include<iostream&g ...

  6. 二叉树层序遍历 c语言,C语言按层次遍历二叉树算法

    下面是编程之家 jb51.cc 通过网络收集整理的代码片段. 编程之家小编现在分享给大家,也给大家做个参考. #define MaxSize 1000 typedef char ElemType; t ...

  7. LeetCode 107. 二叉树的层次遍历 II(队列)

    1. 题目 给定一个二叉树,返回其节点值自底向上的层次遍历. (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历) 例如: 给定二叉树 [3,9,20,null,null,15,7],3/ \9 ...

  8. 网易:层次遍历二叉树

    题目描述 分层遍历二叉树 用java实现树结构,分层遍历二叉树.给定一棵二叉树,要求按分层遍历该二叉树,即从上到下按层次访问该二叉树(每一层单独输出一行),每一层要求访问的顺序为从左到右,再按照相同规 ...

  9. java层次遍历建立二叉树_java层次遍历二叉树

    思路很简单.通过队列,先将头结点放入队列,再遍历每个节点的左节点和右节点. import java.util.ArrayList; import java.util.LinkedList; /** * ...

最新文章

  1. 【新无人机数据集】从 行人重识别 到 无人机目标定位
  2. 设计立方体类(求出立方体的面积和体积 分别用全局函数和成员函数判断两个立方体是否相等)
  3. matlab 角域重采样,matlab滤波技术与区域处理---区域滤波
  4. 辽宁省计算机专业最好的本科学校有哪些,辽宁省哪所大学最好-辽宁省排名前十的大学排名...
  5. 面试常见问题_软件实施工程师面试中的常见问题都有哪些呢?
  6. 服务高可用:幂等性设计
  7. 腾讯为什么不开发linux软件下载,你认为国产操作系统如何搭建生态?为什么腾讯不给Linux系统适配QQ?...
  8. oracle11g memory_target,Oracle11g启动报:ORA-00845: MEMORY_TARGET not supported on this system
  9. 苹果手机内存怎么查_为什么苹果手机内存越用越小
  10. 程序人生:做技术,切不可沉湎于技术
  11. mysql+索引+rebuild_(solr系列:五) solr定时实时重建索引和增量更新
  12. arguments.callee 指向正在执行的函数的指针
  13. Flutter实战之FlutterPlugin插件入门指南
  14. java final修饰的数组_Java基于final修饰数据过程解析
  15. Smart Beta是什么?
  16. 喝一口肾没了:全球最贵10款矿泉水
  17. Windows Home Server V2 Code Name Vail Preview
  18. CRM管理软件有哪些?这5款好用的CRM软件值得推荐!
  19. 【软件下载】Excel下载 word下载 官方 官网下载 原始镜像 开发工具 开发软件下载
  20. Solidworks模板及设计库方便设计者调用

热门文章

  1. 【状压DP】CQBZOJ3646 炼金术师
  2. 审评(HelloWorld团队)
  3. moto x android 6.0,MOTOXPRO升级安卓6.0
  4. SIGGRAPH2005!!!
  5. C语言项目:别踩白块游戏(双人版),450行源码分享+详细思路
  6. 3A信用评级认证的好处
  7. ArcGIS和经济引力模型的城市联系度分析
  8. 引力搜索算法(Gravitational_Search_algorithm,GSA)附matlab代码
  9. react怎么连接打印机_React Native Socket 连接打印机推送指令
  10. OpenAI CEO喊麦ChatGPT:你很酷,但却是个“糟糕的产品”