层次遍历二叉树

news2024/11/16 10:50:26

层次遍历二叉树

文章目录

  • 层次遍历二叉树
    • ♥ 做法
    • ♥算法构思
    • ♥ 数据结构设计
    • ♥ 层次遍历过程
    • ♥ 算法实现
  • 应用:用层次遍历求路径之逆
      • ♥ 问题
      • ♥ 解题思路:
      • ♥ 算法框架:
      • ♥ 算法实现

♥ 做法

image-20221210161332715

▪ 逐层进行访问

▪ 对某一层的节点访问完后,再按照其访问次序对各个节点的左、右孩子顺序访问。

♥算法构思

既然我们了解了层次遍历的次序, 那接下来就是层次遍历的设计,我们是逐层遍历,在同一层次上面的节点,先遍历的节点,其孩子在下一层也有优先权,所以我们在遍历到一个节点时,其孩子也要进入排队的序列。我们根据优先权,先进来要求先出,所以我们可以采用队列的形式,逐层的去存储要出队遍历的节点。

唯一需要注意的就是,当遍历一个节点的时候,我们要把其孩子入队,以方便下一层节点的有序遍历。

当然,由于节点的个数不确定,我们可以采用环形队列的方式进行数据结构存储。

♥ 数据结构设计

▪ 先访问的节点,其左、右孩子也要先访问

▪ 先进先出

▪ 用队列实现

▪ 用环形队列实现

♥ 层次遍历过程

▪ 先将根节点进队

▪ 节点出队并访问,再将左右孩子入队

▪ 循环,直到队空

♥ 算法实现

//传入要层次遍历的树
void LevelOrder(BTNode *b)
{
    //定义遍历节点的指针
    BTNode *p;
    //定义存储遍历节点次序的数组队
    BTNode *qu[MaxSize];
    //定义队的队头和队尾
    int front,rear;
    //初始化队列
    front = rear = -1;
    //我们先将根节点入队
    rear++;
    qu[rear]=b;
    //接下来就是遍历节点,然后将其孩子加入队列,按层次遍历的过程了
    while(front!=rear)
    {
        //从队列中出列一个节点*p,访问它;
        front = (front+1)%MaxSize;
        p = qu[front];
        printf("%c",p->data);
        //若它有左孩子节点,将其左孩子节点进队
        if(p->lchild!=NULL)
        {
            rear = (rear+1)%MaxSize;
            qu[rear] = p->lchild; 
        }            
        //若它有右孩子节点,将右孩子节点进队
        if(p->rchild!=NULL)
        {
            rear = (rear+1)%MaxSize;
            qu[rear] = p->rchild; 
        }            
    }        
}    

应用:用层次遍历求路径之逆

♥ 问题

二叉树采用二叉链存储结构,设计算法输出从根节点到每个叶子节点的路径之逆

♥ 解题思路:

image-20221210164427683

既然要求路径之逆,那么就需要让节点知道其双亲是谁, 我们可以通过遍历给每个节点编号,定义每个节点的双亲信息。既然要定义存储其双亲信息,那我们我们就需要遍历二叉树,那就非层次遍历莫属了,因为层次遍历没有递归遍历的冗余信息,没有先序遍历、中序遍历、后续遍历来回操作的烦恼,只需要按部就班的进行进队和出队节点即可,方便我们进行遍历每个节点。并且我们在处理一个节点的时候,会把其孩子入队,此时我们就可以把节点的信息,告诉其孩子,并存储到数组里面,方便后续我们进行求路径之逆。

♥ 算法框架:

结合层次遍历的特点,给出解题框架

▪ 采用非环形顺序队列qu

▪ 层次遍历二叉树

▪ 将所有已访问过的节点指针进队,并在队列中保存双亲节点的位置

▪ 当找到一个叶子结点时,在队列中通过双亲节点的位置输出根节点到该叶子节点的路径之逆。

image-20221210165335289
void AllPath2(BTNode*b)
{
    定义队列;
    根节点入队;
    while(队列不空)
    {
        if(检查是否是叶子节点)
        {
            如果是,就根据标记输出叶子节点到跟节点的路径
        }            
    }        
    //继续遍历二叉树,把每一个节点赋值到数组里面,并将双亲信息给孩子
    左孩子先入队;
    右孩子入队;
}    
__________________________________________________________________________________
    我们不用担心,已经填入的数组的节点不够用,不足以找到其双亲,因为我们是按照层次遍历的二叉树,
如果遍历到一个节点是叶子节点,那其双亲一定在数组里面,我们也一定可以找到,因为我们就是根据其
双亲才将节点入队访问的,都是按照层次进行访问的,其上层一定在数组里面,边访问,边输出即可。

♥ 算法实现

//传入二叉树
void AllPath2(BTNode *b)
{
    //定义访问的节点的指针
    BTNode *q;
	//定义存储双亲信息的数组节点
    struct snode
    {
        //存储节点的值
        BTNode *node;
        //存储节点双亲在数组里的位置
        int parent;
    }qu[MaxSize];        
    //因为我们是按照层次进行遍历的,所有节点都是按顺序填入数组的,我们可以将此存储双亲信息的数组当成队列去使用
	//我们此次没有出队节点的需要,所以不会破坏队列的数据
    //初始化队列
    int front,rear,p;
    front = rear = -1;
    //入队根节点
    rear++;
    qu[rear].node = b;
    qu[rear].parent = -1;	//根节点无双亲,所以记作-1
    //下面开始遍历访问节点,并填入数组,如果遇到叶子节点,根据双亲信息输出即可
	//队列不空
    while(front!=rear)
    {
        //访问队头节点
        front++;
        q = qu[front].node;
        //判断叶子节点,输出路径之逆
        if(q->lchild==NULL && q->rchild==NULL)
        {
            //通过上面的验证,说明队首节点就是叶子节点
            p = front;
            while(qu[p].parent!= -1)
            {
                printf("%c->",qu[p].node->data);
                //遍历赋值叶子节点路径上的双亲数组序号
                p = qu[p].parent;
            }                
            printf("%c\n",qu[p].node->data);
        }            
        //左孩子入队
        if(q->lchild!=NULL)
        {
            rear++;
            //入队的节点
            qu[rear].node = q->lchild;
            //入队节点的双亲是队首节点
            qu[rear].parent = front;
        }            
        //右孩子入队
        if(q->rchild!=NULL)
        {
            rear++;
			//入队的节点
            qu[rear].node = q->rchild;
            //入队节点的双亲是队首节点
            qu[rear].parent = front;
        }            
    }        
}    
    

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/78513.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[附源码]Python计算机毕业设计SSM基于的在线怀旧电影歌曲听歌系统(程序+LW)

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

MATLAB算法实战应用案例精讲-【神经网络】扩散模型(Diffusion Models)

前言 广播模型、扩散模型和传染模型可以用于分析信息、技术、行为、信念和传染病在人群中的传播。这些模型在通信科学、市场营销学和流行病学的研究中发挥着核心作用。 在计算机视觉中,生成模型是一类能够生成合成图像的模型。例如,一个被训练来生成人脸的模型,每次都会生…

Java项目:SSM电子书网站管理系统

作者主页:源码空间站2022 简介:Java领域优质创作者、Java项目、学习资料、技术互助 文末获取源码 项目介绍 本项目包含管理员、用户两种角色; 管理员角色包含以下功能: 登录页面,管理员管理书籍,用户管理等功能。 用户角色包含…

Docker学习笔记4(狂神)

DockerFile 很多官方镜像都是基础包,很多功能没有,我们通常会自己搭建自己的镜像! 官方既然可以制作镜像,那我们也可以! DockerFile的构建过程 很多指令: 创建一个自己的centos: 我们可以看到我们从docke…

代码随想录训练营第四天

专题:链表 题目:两两交换链表中的节点 给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。 你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。 例如: 题目分析 要两两交换链表中的结…

python opencv 找到圆点标定板所有点后通过距离找两个角点6

先对大图中的标定板框选,然后再标定计算 工程目录结构 如果提示没有win32gui则 pip install pywin32 如果是conda的环境则 conda install pywin32 drawROI.py import copy import jsonimport cv2 import numpy as np import os import matplotlib.pyplot as plt f…

【计算机视觉】Keras API和Tensorflow API的讲解(超详细必看)

觉得有帮助麻烦点赞关注收藏~~~ 一、Keras API Keras是一个用Python编写的高级神经网络API,它能够以Tensorflow、CNTK或者Theano作为后端运行,是一个模块化,最小化并且非常容易扩展的架构,它的开发者Francois Chollet说&#xff…

ESP32 ESP-IDF LVGL8.3.3 ST7735颜色修正

陈拓 2022/12/07-2022/12/10 1. 概述 在《ESP32 ESP-IDF LVGL8.3.3移植(ST7735)》 ESP32 ESP-IDF LVGL8.3.3移植_晨之清风的博客-CSDN博客ESP32 ESP-IDF LVGL8.3.3移植。https://blog.csdn.net/chentuo2000/article/details/128269394?spm1001.2014.3001.5502​​​​​​​…

Python 工匠 第四章 条件分支控制流

基础知识 分支惯用写法 没必要显式和布尔值比较,直接: if user.is_active:pass省略零值判断 if containers_count 0: --> if not containers_count: # 因为bool(0): False但是两者仍有不同 前者只有为0的时候才满足条件 后者则扩大到0, None, 空…

说说Vue-Router和Vue组件中的name属性的使用区别

目录 ⏬ Vue路由匹配规则routes中的name属性的使用 1. 指定页面路由,并传递参数 2. 获取组件的name值,以供页面使用 3. 同个路由,渲染多个视图 ⏬ vue组件中name的使用 1、组件递归操作 2、配合keep-alive对组件缓存做限制 3、在dev-to…

SpringBoot---错误处理机制

PostManHttp请求模拟工具,软件下载链接如下 PostMan下载链接 如果是其他客户端,默认响应一个JSON数据 原理-----SpirngMVC错误处理的自动配置 可以参照ErrorMvcAutoConfiguration;错误处理的自动配置; 给容器中添加了以下组件: …

基于51单片机的多功能电子时钟设计

设计任务: 1、设计任务:利用单片机、时钟芯片 DS1302、温度传感器 DS18B20、1602 液晶 等实现日期、时间、温度的显示即一个简单的万年历。 2、设计要求 (1)通过 DS1302 能够准确的计时,时间可调并在液晶上显示出来…

RK3568平台开发系列讲解(驱动基础篇)Linux内核面向对象思想之封装

🚀返回专栏总目录 文章目录 一、链表的抽象与封装二、设备管理模型的抽象与封装三、总线设备模型的抽象与封装沉淀、分享、成长,让自己和他人都能有所收获!😄 📢Linux内核虽然是使用C语言实现的,但是内核中的很多子系统、模块在实现过程中处处体现了面向对象编程思想。…

动态规划:将题目转换为01背包问题

文章目录494. 目标和474. 一和零494. 目标和 力扣传送门: https://leetcode.cn/problems/target-sum/ 题目描述: 给你一个整数数组 nums 和一个整数 target 。 向数组中的每个整数前添加 ‘’ 或 ‘-’ ,然后串联起所有整数,可以…

easyrecovery2023最新免费版电脑数据恢复软件使用教程

easyrecovery2023版能实现多种不同格式的完成修复和进程的解决,能进行数据的操作和保存解决完成,通过不同的内容进行操作,能解决大部分的使用问题,能安全的进行保存。easyrecovery免安装版对于多种格式下的内容,能对多…

nacos注册中心和配置中心

nacos注册中心和配置中心 nacos 一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。 nacos官方文档:https://nacos.io/zh-cn/ 相关概念:https://nacos.io/zh-cn/docs/architecture.html nacos是AP架构,注重可用性和分区容错性&#…

腾讯云双十二服务器2核2G、2核4G、4核8G、8核16G、16核32G配置价格表出炉

现在腾讯云服务器2核2G、2核4G、4核8G、8核16G、16核32G配置价格表已经出来了,大家可以参考一下。腾讯云轻量应用服务器为轻量级的云服务器,使用门槛低,按套餐形式购买,轻量应用服务器套餐自带的公网带宽较大,4M、6M、…

​软件测试之“支付功能”测试

01 测试思维 要分析测试点之前,我们先来梳理一下测试思维。总结来说,任何事物的测试思路都可以总结如下: 第一步:梳理产品的核心业务流程:明白这是个什么项目,实现了什么业务,以及是怎么实现的…

电动汽车电池换电站选址与定容(Matlab代码实现)

💥💥💥💞💞💞欢迎来到本博客❤️❤️❤️💥💥💥 🎉作者研究:🏅🏅🏅主要研究方向是电力系统和智能算法、机器学…

python学习笔记(13)---(IO对象序列化)面向对象

目录 面向对象---第十一章 IO对象序列化 1.IO流(IO stream) 2.open()方法 3.写入方法:write() 4.对象序列化 面向对象---第十一章 IO对象序列化 1.IO流(IO stream) (1&…