二叉树的层序遍历(两种方法实现)

二叉树的层序遍历(两种方法实现)两种方法实现二叉树的层序遍历1、说明二叉树的层序遍历是面试经常会被考察的知识点,甚至要求当场写出实现过程。层序遍历所要解决的问题很好理解,就是按二叉树从上到下,从左到右依次打印每个节点中存储的数据。如下图:先序遍历:A→B→D→C中序遍历:B→D→A→C后续遍历:D→B→C→A层序遍历:A→B→C→…

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


两种方法实现二叉树的层序遍历

1、说明

二叉树的层序遍历是面试经常会被考察的知识点,甚至要求当场写出实现过程。

层序遍历所要解决的问题很好理解,就是按二叉树从上到下,从左到右依次打印每个节点中存储的数据。如下图:

这里写图片描述

先序遍历:A → B → D → C
中序遍历:B → D → A → C
后续遍历:D → B → C → A
层序遍历:A → B → C → D

2、实现

队列实现:
  • 仔细看看层序遍历过程,其实就是从上到下,从左到右依次将每个数放入到队列中,然后按顺序依次打印就是想要的结果。

  • 实现过程
    1、首先将二叉树的根节点push到队列中,判断队列不为NULL,就输出队头的元素,
    2、判断节点如果有孩子,就将孩子push到队列中,
    3、遍历过的节点出队列,
    4、循环以上操作,直到Tree == NULL。

void FloorPrint_QUEUE(pTreeNode &Tree) //层序遍历_队列实现
{
    queue < pTreeNode> q;
    if (Tree != NULL)
    {
        q.push(Tree);   //根节点进队列
    }

    while (q.empty() == false)  //队列不为空判断
    {
        cout << q.front()->data << " → "; 

        if (q.front()->leftPtr != NULL)   //如果有左孩子,leftChild入队列
        {
            q.push(q.front()->leftPtr);   
        }

        if (q.front()->rightPtr != NULL)   //如果有右孩子,rightChild入队列
        {
            q.push(q.front()->rightPtr);
        }
        q.pop();  //已经遍历过的节点出队列
    }
}
数组实现:
  • 实现过程
    1、创建一个指针数组,保存二叉树结构体指针,
    2、保存二叉树根节点,再申请变量 in、out ,控制数组,在遍历过程中,始终能找到节点和该节点的前一个节点,
    3、循环以上过程。
void FloorPrint(pTreeNode Tree)  //层序遍历
{
    pTreeNode temp[100];   //创建pTreeNode指针类型的指针数组
    int in = 0;
    int out = 0;

    temp[in++] = Tree;  //先保存二叉树根节点 

    while (in > out)
    {
        if (temp[out])
        {
            cout << temp[out]->data << " → ";
            temp[in++] = temp[out]->leftPtr;
            temp[in++] = temp[out]->rightPtr;
        }
        out++;
    }
}

3、完整代码

bintree.h

#ifndef __BINTREE_H__
#define __BINTREE_H__

#include<iostream>
#include<cstring>
#include<cassert>
#include<queue>

using namespace std;

typedef char DataType;

struct TreeNode {

    DataType data;    /* node data */

    struct TreeNode *leftPtr;   /* pointer to left subtree */

    struct TreeNode *rightPtr;  /* pointer to right subtree */
};

typedef struct TreeNode TreeNode;

typedef TreeNode * pTreeNode;

void CreateBinTree(pTreeNode *Tree);//创建二叉树

void InitTreeNode(pTreeNode *Tree);//初始化

void PreOrderPrint(pTreeNode Tree);//先序遍历

void MidOrderPrint(pTreeNode Tree);//中序遍历

void PostOrderPrint(pTreeNode Tree);//后续遍历

void FloorPrint(pTreeNode Tree);//层序遍历

void FloorPrint_QUEUE(pTreeNode &Tree);//层序遍历_队列实现

#endif

bintree.cpp

#include"binterr.h"

void InitTreeNode(pTreeNode *Tree)
{
    *Tree = NULL;
}

void CreateBinTree(pTreeNode *Tree)
{
    DataType ch;
    ch = getchar();
    if (ch == '#')
    {
        *Tree = NULL;
    }
    else
    {
        *Tree = (pTreeNode)malloc(sizeof(pTreeNode));

        if (NULL == (*Tree))
        {
            exit(0);
        }
        else
        {
            (*Tree)->data = ch;
            (*Tree)->leftPtr = NULL;
            (*Tree)->rightPtr = NULL;
            CreateBinTree(&(*Tree)->leftPtr); CreateBinTree(&(*Tree)->rightPtr); } } } void PreOrderPrint(pTreeNode Tree) { if (!Tree) { return; } cout << Tree->data << " → ";
    PreOrderPrint(Tree->leftPtr);
    PreOrderPrint(Tree->rightPtr);
}

void MidOrderPrint(pTreeNode Tree)//中序遍历
{
    if (NULL != Tree)
    {
        PreOrderPrint(Tree->leftPtr);
        cout << Tree->data << " → ";
        PreOrderPrint(Tree->rightPtr);
    }
}

void PostOrderPrint(pTreeNode Tree)//后续遍历
{
    if (NULL != Tree)
    {
        PreOrderPrint(Tree->leftPtr);
        PreOrderPrint(Tree->rightPtr);
        cout << Tree->data << " → ";
    }
}

void FloorPrint(pTreeNode Tree)  //层序遍历
{
    pTreeNode temp[100];   //创建pTreeNode指针类型的指针数组
    int in = 0;
    int out = 0;

    temp[in++] = Tree;  //先保存二叉树根节点 

    while (in > out)
    {
        if (temp[out])
        {
            cout << temp[out]->data << " → ";
            temp[in++] = temp[out]->leftPtr;
            temp[in++] = temp[out]->rightPtr;
        }
        out++;
    }
}

void FloorPrint_QUEUE(pTreeNode &Tree) //层序遍历_队列实现
{
    queue < pTreeNode> q;
    if (Tree != NULL)
    {
        q.push(Tree);   //根节点进队列
    }

    while (q.empty() == false)  //队列不为空判断
    {
        cout << q.front()->data << " → "; 

        if (q.front()->leftPtr != NULL) //如果有左孩子,leftChild入队列 { q.push(q.front()->leftPtr); } if (q.front()->rightPtr != NULL) //如果有右孩子,rightChild入队列 { q.push(q.front()->rightPtr); } q.pop(); //已经遍历过的节点出队列 } }

test.cpp

#include"binterr.h"

void test()
{
    pTreeNode T;
    InitTreeNode(&T);

    CreateBinTree(&T);  //创建一个二叉树

    cout << "前序遍历:" << endl;
    PreOrderPrint(T);    //前序遍历

    cout << "\n中序遍历:" << endl;
    MidOrderPrint(T);   //中序遍历

    cout << "\n后序遍历:" << endl;
    PostOrderPrint(T);   //后续遍历

    cout << "\n层序遍历:" << endl;
    FloorPrint(T);

    cout << "\n层序遍历——Queue:" << endl;
    FloorPrint_QUEUE(T);
}

int main(void)
{
    test();
    return 0;
}

4、结果截图

这里写图片描述

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

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

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


相关推荐

  • Java 集合详解

    Java 集合详解Java集合详解1.集合了解集合类存放于java.util包中。集合类存放的都是对象的引用,而非对象本身。集合的长度可变。2.集合层次关系观看上图需要注意一下实线边框的是实现类折线边框的是抽象类点线边框的是接口2.1Collection接口Collection接口是集合类的根接口,Java中没有提供这个接口的直接的实现类。但是却让其被继承产…

    2022年5月18日
    33
  • 在pycharm里面对文件夹或者文件进行重命名的一种方法「建议收藏」

    在pycharm里面对文件夹或者文件进行重命名的一种方法「建议收藏」因为你要进行重命名的文件有可能当前被引用着,你修改之后,原本可以跑通的程序有可能跑不通了。所以重命名输入重构(Refactor)的内容,所以在project选项卡中,选中文件或者文件名称,右键选择Refactor,再选择Rename即可。如图所示:随后会弹出 第一个是查找是不是有代码应用了它,第二个复选框含义是是否在注释和字符串中查找这个名称。有时候你需要修改重命名文件的相关引…

    2022年8月26日
    5
  • PyCharm激活码永久有效PyCharm2020.3.4激活码教程-持续更新,一步到位

    PyCharm激活码永久有效PyCharm2020.3.4激活码教程-持续更新,一步到位PyCharm激活码永久有效2020.3.4激活码教程-Windows版永久激活-持续更新,Idea激活码2020.3.4成功激活

    2022年6月19日
    45
  • 微信公众号开发系统入门教程(公众号注册、开发环境搭建、access_token管理、Demo实现、natapp外网穿透)

    微信公众号开发系统入门教程(公众号注册、开发环境搭建、access_token管理、Demo实现、natapp外网穿透)微信公众号主要有以下几个步骤微信公众号的通讯机制微信公众号简介1.注册微信公众号2.注册测试公众号3.搭建微信本地调试环境1)下载客户端natapp:2)安装natapp:4.微信公众号接入(校验签名)第1步中服务器配置包含服务器地址(URL)、令牌(Token)和消息加解密密钥(EncodingAESKey)。第2步,验证服务器地址的有效性,当点击“提交”…

    2022年6月6日
    26
  • 教你如何免费使用云服务器「建议收藏」

    教你如何免费使用云服务器「建议收藏」深度学习没有GPU?!!教你如何白嫖服务器一、声明二、引言二、如何获取三、操作步骤3.1文件传输软件的安装3.3远程操控软件的安装四、资料软件分享五、总结教你如何白嫖服务器)一、声明本文章没有广告用意,只是觉得好用分享给大家。同时做个简单的记录。二、引言因为电脑只有CPU,算力不够,以及很多深度学习教程以及模型都是在GPU环境下进行,所以一直想着怎么样才能白嫖到服务器,毕竟云服务器不便宜,要是经常用的话,对学生党来说是一笔不小的支出。有一天经过群友推荐终于找到了一个可以免费试用200元的云服

    2022年9月26日
    1
  • 树莓派4b基础入门「建议收藏」

    树莓派4b基础入门「建议收藏」目录一、树莓派百科知识二、树莓派4B图解及配件选择三、如何烧录系统?四、树莓派开机连接五、常见警示标志和故障排除六、格式化TF卡七、系统备份与恢复八、无线WiFi上网配置九、系统汉化教程十、键盘布局设置十一、树莓派扩展分区十二、开启SSH的4种方法十三、开启VNC的3种方法十四、Windows远程桌面连接十五、获取IP和MAC地址十六、设置静态IP十七、常见问题一、树莓派百科知识树莓派(RaspberryPi)是一款基于ARM的微型电脑主板,旨为学生计算机编程教育而设计,其系统基于Linux,由注册于

    2022年6月11日
    123

发表回复

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

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