【数据结构OJ】BFS算法的可视化:二叉树“层序遍历”

【数据结构OJ】BFS算法的可视化:二叉树“层序遍历”

今天我们来分享一道关于二叉树层序遍历的OJ算法题

目录

题目介绍:

1、核心定义

2、实现核心及思路

解题思路:

思路可视化:

代码实现:

代码测试:


题目介绍:

接口函数以及二叉树节点结构:

/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode() : val(0), left(nullptr), right(nullptr) {} * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} * }; */ class Solution { public: vector<vector<int>> levelOrderBottom(TreeNode* root) { } };

题目来源:leetcode:107.二叉树的层序遍历II

1、核心定义

二叉树的层序遍历,又称广度优先遍历(BFS),是指从根节点开始,按“从上到下、从左到右”的顺序逐层访问树中所有节点,先遍历完第1层(根节点),再遍历第2层,以此类推,直到最后一层的所有节点都被访问。

2、实现核心及思路

二叉树层序遍历的本质就是 “先进先出” 的访问逻辑队列是实现该逻辑给关键数据结构。



大概思路:我们可以将二叉树的节点的地址存入队列,同时,用一个level_k_size来记录每一层的节点个数,和一个数组 v 来存储每一层数据,然后利用" level_k_size-- " 来控制节点出队列的个数,保证每一层的节点都能够出尽,在节点出队列的同时将节点的val值插入数组v并将该节点不为空的孩子节点继续带入队列;这样利用 level_k_size每循环一次得到一层的数据,直到遍历完整个二叉树。

解题思路:

(1)通过题目介绍,我们知道函数最后需要返回vector<vector<int>>的二维数组,所以,我们先创建一个二维数组 vv

(2)判断二叉树是否为空,即根结点root是否为nullptr。若为空则则不做处理,最后返回一个空的二维数组vv;不为空,则将根结点root入队列,同时 level_k_size记录节点个数为1

(3)根据level_k_size来遍历已经入队列的节点。由于level_k_size记录的是对应一层的节点数,就可以用 level_k_size作为while循环的循环次数来遍历节点利用队列的front接口函数获取队头的节点,将队头节点的val值插入到数组v(可以用vector创建数组),然后,将该节点不为空的孩子节点带入队列,同时,将队头节点出队列(pop)

⭐️注意:a.  这里不能直接将节点直接出队列,防止节点被释放而找不到孩子节点。可以用node记下该节点,然后pop(删除队头节点)。

b. 每次出队头节点都要保证将其对应的不为空的左右孩子节点带入队列,保证在下一次遍历时,已经出队列的节点的下一层的所有节点都在队列中,便于准确更新level_k_size的值。

(4)遍历完一层的节点之后,将数组v中的数据插入(push_back)到二维数组vv,然后更新level_k_size的值,得到下一层节点的个数。

(5)当队列中再没有节点时,证明二叉树的所有节点已经都遍历完了,因为上一层节点的左右孩子节点都为空,即二叉树遍历完成。但是,题目要求我们从二叉树的叶子节点所在层开始向上遍历,所以,我们先将二维数组vv进行逆置处理(reverse),再返回即可。

思路可视化:

代码实现:

class Solution { public: vector<vector<int>> levelOrderBottom(TreeNode* root) { vector<vector<int>> vv; // 创建二维数组 int level_k_size=0; if(root!=nullptr) { _q.push(root); // 插入根结点 level_k_size=1; // 记录节点个数 } while(!_q.empty()) { vector<int> v; // 创建数组v while(level_k_size--) // 遍历一层 { TreeNode* node=_q.front(); //记下队头节点 _q.pop(); // 释放 v.push_back(node->val); // 将数据插入到v if(node->left) // 带入左孩子节点 { _q.push(node->left); } if(node->right) // 带入右孩子节点 { _q.push(node->right); } } vv.push_back(v); // 将数组v的数据插入二维数组 level_k_size=_q.size(); // 更新level_k_size的值 } reverse(vv.begin(),vv.end()); // 逆置 return vv; } private: queue<TreeNode*> _q; // 成员变量(队列) };

代码测试:

int main() { solution s; // 创建一棵二叉树 TreeNode node1(3); TreeNode node2(9); TreeNode node3(20); TreeNode node4(15); TreeNode node5(15); TreeNode node6(7); // 连接 node1._left = &node2; node1._right = &node3; node2._left = &node4; node3._left = &node5; node3._right = &node6; vector<vector<int>> vv; vv = s.levelOrderTravelsal(&node1); // 调用函数 for (int i = 0; i < 3; i++) { for (int j = 0; j < vv[i].size(); j++) { cout << vv[i][j] << " "; } cout << endl; } }

本期的分享就到此结束👇️👇️👇️

Read more

GoWeb必备理论

GoWeb必备理论

关于goweb,你不得不知道的知识 若是初学者可以借鉴GoWeb查阅本文。 HTTP状态码: 意义 每个状态码都是,http设计者对“网络通讯”中可能出现的情况的假设、预判。他就相当于现实世界的信号灯,就像大家一遇到404,就知道资源找不到了。一遇到500就知道服务器挂了。这种共识,也就是如今万维网的高效率的基础之一。 http状态码是日常开发,修改bug,的居家必备神器。咱们对常见状态码做了分类。 1、必须掌握的状态码 200 ok 最常见的状态码,代表请求完全正确,比如打开网页、调用api啥的。 301 moved permanently 资源永久迁移(例:访问时a.com会被从定项到b.com) 302 Found (部分资源,临时迁移) 400 Bad request(请求出错,参数缺少什么的..) 401 unauthorized(没有登入) 403 forbidden(

By Ne0inhk
Flutter for OpenHarmony:web 拥抱 Web 标准的桥梁(Wasm GC 与 DOM 互操作) 深度解析与鸿蒙适配指南

Flutter for OpenHarmony:web 拥抱 Web 标准的桥梁(Wasm GC 与 DOM 互操作) 深度解析与鸿蒙适配指南

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net 前言 随着 Flutter 3.x 全面拥抱 Wasm(WebAssembly),Dart 团队推出了全新的 package:web 来取代老旧的 dart:html。 package:web 是基于最新的 JS Interop 机制构建的,它不仅性能更好,而且兼容 Wasm GC 标准。 虽然这个库通过名字看是为 “Web” 平台的,但对于 OpenHarmony 开发者来说,了解它有着特殊的意义: 1. 混合开发:鸿蒙原生支持 ArkWeb (WebView),在 Flutter 中通过 JS互操作与 Web 页面交互是常见需求。 2.

By Ne0inhk

前端新手必学:5分钟搞定postcss-px-to-viewport

快速体验 1. 打开 InsCode(快马)平台 https://www.inscode.net 2. 点击'项目生成'按钮,等待项目生成完整后预览效果 输入框内输入如下内容: 请创建一个面向新手的postcss-px-to-viewport教学示例,要求:1. 从创建Vue/React项目开始 2. 分步讲解安装和配置过程 3. 提供最简单的配置示例 4. 包含常见错误排查方法 5. 最终输出一个可运行的demo项目。请使用最基础的配置,并添加大量注释和说明文字。 作为一名前端新手,在开发移动端页面时,最头疼的问题之一就是如何让页面在不同尺寸的设备上都能正常显示。传统的px单位在移动端适配中显得力不从心,这时候就需要用到postcss-px-to-viewport这个神器了。今天我就来分享一下我的学习心得,手把手教你如何快速上手这个工具。 1. 为什么要用postcss-px-to-viewport 在移动端开发中,我们经常需要根据设备宽度来调整元素尺寸。postcss-px-to-viewport可以将px单位自动转换为vw单位(视窗宽度单位),实现真正的响应式布局

By Ne0inhk

OpenClaw Webhook 详解:完整指南

Webhook 是将 OpenClaw 从“聊天助手”快速转变为“响应式系统”的最佳方式。无需等待您主动发送消息,GitHub 可以在 PR 提交时通知 OpenClaw,Stripe 可以在支付失败时通知 OpenClaw,n8n 也可以按计划通知 OpenClaw。OpenClaw 会接收这些传入事件,并将其转换为代理运行或轻量级唤醒操作,然后将结果路由回您实际使用的任何渠道。 本文重点介绍 OpenClaw 网关上的 HTTP Webhook。OpenClaw 中还有另一种东西,在一些文档和配置中也被称为“钩子”。这些是网关内部的事件钩子,当本地生命周期事件触发时运行。它们也很有用,但 Stripe 或 GitHub 与服务器通信的方式并非通过它们。 如果您的 OpenClaw 实例是刚刚部署在 VPS 上,并且您仍然使用 SSH 进行基本操作,那么首先要确保网关稳定,

By Ne0inhk