数据结构 ——— 层序遍历链式二叉树

目录

链式二叉树示意图​编辑

何为层序遍历

手搓一个链式二叉树

实现层序遍历链式二叉树 


链式二叉树示意图


何为层序遍历

和前中后序遍历不同,前中后序遍历链式二叉树需要利用递归才能遍历
而层序遍历是非递归的形式,如上图:层序遍历的结果:1,2,4,3,5,6


手搓一个链式二叉树

代码演示(以上图为例):

// 数据类型
typedef int BTDataType;// 二叉树节点的结构
typedef struct BinaryTreeNode
{BTDataType data; //每个节点的数据struct BinaryTreeNode* left; //指向左子树的指针struct BinaryTreeNode* right; //指向右子树的指针
}BTNode;// 申请新节点
BTNode* BuyNode(BTDataType x)
{BTNode* newnode = (BTNode*)malloc(sizeof(BTNode));// 判断是否申请成功if (newnode == NULL){perror("malloc fail");return NULL;}// 初始化newnode->data = x;newnode->left = NULL;newnode->right = NULL;return newnode;
}BTNode* CreatBinaryTree()
{BTNode* n1 = BuyNode(1);assert(n1);BTNode* n2 = BuyNode(2);assert(n2);BTNode* n3 = BuyNode(3);assert(n3);BTNode* n4 = BuyNode(4);assert(n4);BTNode* n5 = BuyNode(5);assert(n5);BTNode* n6 = BuyNode(6);assert(n6);n1->left = n2;n1->right = n4;n2->left = n3;n4->left = n5;n4->right = n6;return n1;
}

实现层序遍历链式二叉树

实现思路:

利用队列的先进先出的性质,实现层序遍历链式二叉树
如上图所示:先将 1 节点入队列,再将 1 节点出队列,在 1 节点出队列的时候,把 2、4 节点带入队列,2 节点再出队列,2 节点出队列的时候,把 3 节点带入队列,然后就是 4 节点出队列,同样出队列的时候,将 5、6 节点带入队列,最后再依次出队列,所有数据出完队列后,根据出队列的顺序,就是层序遍历的顺序

实现前要先构建一个简易队列以及队列的基本函数:

// 数据类型
typedef BTNode* QDataType;// 链式队列每个节点的结构
typedef struct QueueNode
{struct QueueNode* next; //指向下一个节点的指针QDataType data; //当前节点的数据
}QNode;// 链式队列的结构
typedef struct Queue
{QNode* phead; //指向队头节点的指针QNode* ptail; //指向队尾节点的指针int size; //队列的总数据个数
}Queue;// 初始化队列
void QueueInit(Queue* pq)
{assert(pq);pq->phead = NULL;pq->ptail = NULL;pq->size = 0;
}// 数据入队列
void QueuePush(Queue* pq, QDataType x)
{assert(pq);// 申请新节点QNode* newnode = (QNode*)malloc(sizeof(QNode));// 判断是否申请成功if (newnode == NULL){perror("malloc fail");return;}// 初始化新节点newnode->data = x;newnode->next = NULL;if (pq->phead == NULL) //当队列中没有数据的情况{// 双重判断,更加保险assert(pq->ptail == NULL);// 头尾都指向新节点即可pq->phead = newnode;pq->ptail = newnode;}else //当队列已有数据的情况{pq->ptail->next = newnode;pq->ptail = newnode;}pq->size++;
}// 数据出队列
void QueuePop(Queue* pq)
{assert(pq);// 当队列中没有数据的情况if (pq->phead == NULL){perror(pq->phead);return;}if (pq->phead->next == NULL) //当队列中只有一个数据的情况{free(pq->phead);pq->phead = NULL;pq->ptail = NULL;}else //当队列中有多个数据的情况{QNode* next = pq->phead->next;free(pq->phead);pq->phead = next;}pq->size--;
}// 访问队头数据
QDataType QueueFront(Queue* pq)
{assert(pq);// 当队列中没有数据的情况if (pq->phead == NULL){perror(pq->phead);return -1;}return pq->phead->data;
}// 判断队列是否为空
bool QueueEmpty(Queue* pq)
{assert(pq);return (pq->phead == NULL) && (pq->ptail == NULL);
}// 释放队列
void QueueDestroy(Queue* pq)
{assert(pq);QNode* cur = pq->phead;while (cur != NULL){QNode* next = cur->next;free(cur);cur = next;}pq->phead = NULL;pq->ptail = NULL;pq->size = 0;
}

在定义队列数据时,需要定义链式二叉树节点的指针,这样才能找到二叉树节点的左右子树

代码实现:

void LevelOrder(BTNode* root)
{// 定义队列Queue q;// 初始化队列QueueInit(&q);// 先将二叉树的根节点的指针入队列if (root != NULL)QueuePush(&q, root);while (!QueueEmpty(&q)){// 访问队头数据BTNode* front = QueueFront(&q);printf("%d ", front->data);// 队头数据出队列QueuePop(&q);if (front->left)QueuePush(&q, front->left);if (front->right)QueuePush(&q, front->right);}printf("\n");
}

代码解析:

当队列为空时,链式二叉树的层序遍历就实现了
但最开始队列没有数据,所以要先将指向根节点的指针存放入队列
且存放节点指针是为了方便查找左右子树
然后在利用 while 循环,只要队列不为空,就循环下去
先访问队头的数据,队头的数据就是链式二叉树节点的指针
所以使用 BTNode* front 来接收,再利用 printf 函数打印指针所指向节点中的数据
再把队头数据出队列,并且把出队列那个节点的左右子树存放入队列
注意为空时就不要放入队列,所以每次放入队列前要判断是否为空
直到队列为空时,也就是不满足 while 循环时,层序遍历就实现了

此代码的关键是利用 BTNode* front 接收每次要出队列的节点指针,这样就方便查找当前节点的左右子树,并且利用 BTNode* front 接收从而替代了递归逻辑

代码验证:

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

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

相关文章

【故障解决】麒麟系统右下角网络图标取消显示叹号

原文链接:【故障解决】麒麟系统右下角网络图标取消显示叹号 Hello,大家好啊!今天给大家带来一篇关于如何在麒麟系统中解决网络图标出现感叹号问题的文章。在日常使用麒麟系统的过程中,我们在内网或公网环境下,有时会遇…

Spring boot 集成 nacos、redis、mysql

1,准备好nacos环境,准备ncc.yml配置: 在配置添加 test: haha 2,添加依赖 在pom.xml 文件中添加Nacos 客户端的依赖,样例使用Spring Cloud Alibaba 版本使用2023.x 分支,详情可查看 版本发布说明-阿里云S…

力扣 LeetCode 206. 反转链表(Day2:链表)

解题思路: pre ,cur双指针 需要通过tmp暂存cur的下一个位置,以方便cur的下一步移动 class Solution {public ListNode reverseList(ListNode head) {ListNode pre null;ListNode cur head;while (cur ! null) {ListNode tmp cur.next;c…

golang 实现比特币内核:公钥的 SEC 编码格式详解

比特币作为区块链的一个应用,它建立在分布式系统之上,‘节点’遍布全球。为了使所有节点协同工作并作为一个整体系统运行,需要保持所有节点同步在相同的状态中,也就是说节点之间需要频繁通信,并且相互交换大量数据消息。这要求在网络上传输的消息或数据要使用某种格式编码…

v-html 富文本中图片使用element-ui image-viewer组件实现预览,并且阻止滚动条

效果 导入组件 import ElImageViewer from "element-ui/packages/image/src/image-viewer"; components:{ ElImageViewer },模板使用组件 <el-image-viewerv-if"isShowPics":on-close"closeViewer":url-list"srcList"/>定义两…

Redhat7.9 安装 KingbaseES 金仓数据库 V9单机版(图形化安装)

Redhat7.9 安装 KingbaseES 金仓数据库 V9单机版 ——图形化安装 一、安装前规划1.1 安装包下载1.2 环境信息 二、操作系统配置2.1 检查操作系统和内存2.2 关闭防火墙和selinux2.3 配置内核参数(/etc/sysctl.conf)2.4 配置资源使用参数(/etc/security/limits.conf)2.5 配置Remo…

【Linux】进程状态的优先级

大家好呀&#xff0c;我是残念&#xff0c;希望在你看完之后&#xff0c;能对你有所帮助&#xff0c;有什么不足请指正&#xff01;共同学习交流哦 本文由&#xff1a;残念ing原创CSDN首发&#xff0c;如需要转载请通知 个人主页&#xff1a;残念ing-CSDN博客&#xff0c;欢迎各…

【Linux:IO多路复用(select函数)

什么是IO多路复用&#xff1f; 一种网络通信的手段&#xff0c;IO多路复用可以同时监测多个文件描述符&#xff0c;且这个过程是阻塞的&#xff0c;当检测有文件描述符就绪&#xff0c;程序的阻塞就会解除&#xff0c;就可以通过这些就绪的文件描述符进行通信。通过这种方式在…

软件工程笔记二—— 软件生存期模型

目录 瀑布模型 瀑布模型的特点 阶段间具有顺序性和依赖性。 推迟实现的观点 质量保证的观点 瀑布模型的优点 瀑布模型的缺点 快速原型模型 快速原型模型的优点 快速原型模型的缺点 增量模型 增量模型的优点 增量构件开发 螺旋模型 完整的螺旋模型&#xff08;顺…

视频孪生技术在金融银行网点场景中的应用价值

作为国民经济重要的基础行业&#xff0c;金融行业在高速发展的同时衍生出业务纠纷、安全防范、职能管理等诸多问题&#xff0c;对安全防范和监督管理提出了更高的要求。因此&#xff0c;如何能更好的利用视频监控系统价值&#xff0c;让管理人员更简便的浏览监控视频、更快速的…

【金融风控】特征评估与筛选详解

内容介绍 掌握单特征分析的衡量指标 知道 IV&#xff0c;PSI等指标含义 知道多特征筛选的常用方法 掌握Boruta,VIF,RFE,L1等特征筛选的使用方法 【理解】单特征分析 什么是好特征 从几个角度衡量&#xff1a;覆盖度&#xff0c;区分度&#xff0c;相关性&#xff0c;稳定…

LeetCode面试经典150题|228.汇总区间

给定一个 无重复元素 的 有序 整数数组 nums 。 返回 恰好覆盖数组中所有数字 的 最小有序 区间范围列表 。也就是说&#xff0c;nums 的每个元素都恰好被某个区间范围所覆盖&#xff0c;并且不存在属于某个范围但不属于 nums 的数字 x 。 列表中的每个区间范围 [a,b] 应该按…

new Object到底占用多少内存?

前言 通过 JOL 工具&#xff0c;深入剖析对象头、实例数据以及内存对齐的具体细节&#xff0c;了解 JVM 是如何管理和优化内存的。使用 JOL&#xff0c;验证内存结构&#xff0c;直观地观察 JVM 参数&#xff08;如对象指针压缩、类指针压缩等&#xff09;对对象布局的影响。 …

深入理解接口测试:实用指南与最佳实践5.0(二)

✨博客主页&#xff1a; https://blog.csdn.net/m0_63815035?typeblog &#x1f497;《博客内容》&#xff1a;.NET、Java.测试开发、Python、Android、Go、Node、Android前端小程序等相关领域知识 &#x1f4e2;博客专栏&#xff1a; https://blog.csdn.net/m0_63815035/cat…

基于Java+SpringBoot宠物管理系统

一、作品包含 源码数据库设计文档全套环境和工具资源部署教程 二、项目技术 前端技术&#xff1a;Html、Css、Js、Vue、Element-ui 数据库&#xff1a;MySQL 后端技术&#xff1a;Java、Spring Boot、MyBatis 三、运行环境 开发工具&#xff1a;IDEA/eclipse 数据库&…

PYNQ 框架 - 中断(INTR)驱动

目录 1. 简介 2. 分析 2.1 Block Design 2.2 AXI Timer 2.2.1 IP 基本信息 2.2.2 IP 地址空间 2.2.3 级联模式 2.2.4 生成/捕获模式 2.3 AXI Interrupt 2.3.1 IP 基本信息 2.3.2 IP 地址空间 2.3.3 相关概念 2.3.4 参数配置 2.3.5 中断确认寄存器 3. PYNQ 代码 …

使用runtime/pprof包进行Go程序性能调优的实战教程

使用runtime/pprof包进行Go程序性能调优的实战教程 引言基本概念什么是runtime/pprof使用场景 安装和设置环境要求导入runtime/pprof包 基本用法创建和启动一个新的profile停止和销毁一个profile CPU Profiling启动CPU profiling停止CPU profiling分析CPU profiling数据 内存Pr…

深度探秘 VGG 网络:从原理到应用的视觉传奇

VGG 网络的原理 一、整体架构 VGG&#xff08;Visual Geometry Group&#xff09;网络是一种深度卷积神经网络&#xff0c;其显著特点是简洁而高效的架构设计。VGG 网络主要由卷积层、池化层和全连接层组成。 卷积层&#xff1a; 如前所述&#xff0c;VGG 大量使用 的小卷积…

为什么我搞量化分析要特别关注行业产业链

因为看了这本书理论书。我都是用现成的理论来传串起来的。每一步都是背后都有现成的理论支持支撑。虽然看着简单&#xff0c;我这个工具策略参考了投资行为心理学。主要是为了我量身定做的。我也是刚刚研究的新手&#xff0c;碰到的很多问题很多人应该也碰到&#xff0c;就把这…

电商数据接口||淘宝|京东商品详情参数对比

淘宝/天猫获得淘宝商品详情 API 返回值说明 item_get-获得淘宝商品详情 taobao.item_get 公共参数 名称类型必须描述keyString是调用key&#xff08;必须以GET方式拼接在URL中&#xff09;secretString是调用密钥api_nameString是API接口名称&#xff08;包括在请求地址中…