二叉树的层序遍历与深度遍历

news/2024/9/25 4:22:20/

二叉树

今天学习并回顾了二叉树,对其基本算法进行了重写。如有可优化的地方,欢迎指正!代码均在Leetcode上跑过了。

层序遍历(Leetcode102题)

由于用前面写算法都是用C语言写的,像栈、队列每次都得手敲一遍。这里为了简化代码,使用C++进行代码编写。以后也转化为用C++写算法题。
My Coding

class Solution {
public:/*** By passing in a binary tree, return a two-dimensional array to record which nodes are present in each layer** @param root is a pointer to TreeNode type, is the head node of a binary tree** @return a two-dimensional array, with each row corresponding to each layer of the binary tree*/vector<vector<int>> levelOrder(TreeNode* root) {queue<TreeNode*> q;             //创建一个队列vector<vector<int>> vec;        //二维数组,泛型每一行存int型数据if(root == NULL)return vec;     //判断二叉树是否存在vec.push_back(vector<int>());   //预先分配一行int level = 1;                  //到此至少存在一层q.push(root);                   //将root送入队列qmap<TreeNode*,int> m;           //定义一个map,记录每个结点对应的层次m.insert(map<TreeNode*,int>::value_type(root,1));   //map插入数据root,1 表示root在第一层while(!q.empty())               //循环判定队列是否为空,为空则已遍历完{TreeNode *cur = q.front();  //获取队列最前结点q.pop();                    //并将其出队int curLevel = m[cur];      //通过key-value获取其所在层次if(level == curLevel)       //判断level是否等于curLevel,这一步用于判定是否来到下一层{vec[level-1].push_back(cur->val);   //将同一层的结点对应值加入数组中}else    {vec.push_back(vector<int>());       //处于不同层级,新建一行level++;    //更新层级,注意要将当前结点值加入新行数组中vec[level-1].push_back(cur->val);}/* 不用担心cur为空,因为从第一个root开始,只会对不为空的结点进行操作 */if(cur->left != NULL)   //如果左孩子存在,则放入队列并置入哈希表中{m.insert(map<TreeNode*,int>::value_type(cur->left,level + 1));  //左孩子肯定是在下一层q.push(cur->left);}/* 不用担心cur为空,因为从第一个root开始,只会对不为空的结点进行操作 */if(cur->right != NULL)  //如果左孩子存在,则放入队列并置入哈希表中{m.insert(map<TreeNode*,int>::value_type(cur->right,level + 1)); //右孩子肯定是在下一层q.push(cur->right);}}return vec; //返回二维数组。}
};

官方

class Solution {
public:vector<vector<int>> levelOrder(TreeNode* root) {vector <vector <int>> ret;      //创建二维数组if (!root) {                    //判断是否为空,为空则返回return ret;}queue <TreeNode*> q;            //创建队列 qq.push(root);                   //将root加入队列while (!q.empty()) {            //判断二叉树是否遍历完int currentLevelSize = q.size();    //获取当前层级结点个数ret.push_back(vector <int> ());for (int i = 1; i <= currentLevelSize; ++i) {   //循环将数据填入二维数组中auto node = q.front(); q.pop();ret.back().push_back(node->val);if (node->left) q.push(node->left);     //每次将左孩子加入队列(前提不为空)if (node->right) q.push(node->right);   //每次将有孩子加入队列(前提不为空)}}return ret;     返回二维数组}
};

总结: 官方写的更为整洁、简短。值得好好学习。

深度遍历

采用递归算法则相对简单

先序遍历(Leetcode 144题)

递归算法(递归就不分析了)

class Solution {
public:void preorder(TreeNode *root, vector<int> &res) {if (root == nullptr) {return;}res.push_back(root->val);preorder(root->left, res);preorder(root->right, res);}vector<int> preorderTraversal(TreeNode *root) {vector<int> res;preorder(root, res);return res;}
};

非递归算法
注意:压栈一定是先右再左,这样取出来才是先序

class Solution {
public:vector<int> preorderTraversal(TreeNode* root) {vector<int> vec;                //创建一维数组if(root == NULL)return vec;     //如果root为空,则返回stack<TreeNode*> st;            //创建一个栈st.push(root);                  //将root压栈while(!st.empty())              //判断二叉树是否遍历完{   TreeNode* cur = st.top();   //获取栈顶元素st.pop();                   //弹出栈顶元素vec.push_back(cur->val);    //将当前结点值加入数组if(cur->right)              //右孩子不为空则压栈{st.push(cur->right);}if(cur->left)               //左孩子不为空则压栈{st.push(cur->left);}}return vec;     //返回一维数组}
};
中序遍历(Leetcode 94题)

递归算法(递归就不分析了)

class Solution {
public:void preorder(TreeNode *root, vector<int> &res) {if (root == nullptr) {return;}preorder(root->left, res);res.push_back(root->val);preorder(root->right, res);}vector<int> preorderTraversal(TreeNode *root) {vector<int> res;preorder(root, res);return res;}
};

非递归算法

class Solution {
public:vector<int> inorderTraversal(TreeNode* root) {vector<int> vec;    //创建一维数组if(root == NULL)    //如果root为空则返回vec{return vec;}stack<TreeNode*> st;    //创建一个栈while(!st.empty() || root != NULL)  //栈内有值或root不为空时循环{if(root != NULL)    //root不为空,则一直将左孩子压栈{st.push(root);root = root->left;}else                //保存栈顶元素,并将root切换到右孩子{root = st.top();st.pop();vec.push_back(root->val);root = root->right;}}return vec;             //返回一维数组}
};
后序遍历(Leetcode 145题)

递归算法(递归就不分析了)

class Solution {
public:void preorder(TreeNode *root, vector<int> &res) {if (root == nullptr) {return;}preorder(root->left, res);preorder(root->right, res);res.push_back(root->val);}vector<int> preorderTraversal(TreeNode *root) {vector<int> res;preorder(root, res);return res;}
};

非递归算法
采用双栈

class Solution {
public:vector<int> postorderTraversal(TreeNode* root) {vector<int> vec;    //创建一维数组if(root == NULL)    //如果root为空则返回vec{return vec;}stack<TreeNode*> st1;   //栈1stack<TreeNode*> st2;   //栈2st1.push(root);         //root压栈while(!st1.empty())     //第一次遍历完二叉树{root = st1.top();   //弹出栈顶元素st1.pop();st2.push(root);     //将该结点压入栈2if(root->left)      //如果有左孩子,则压栈1{st1.push(root->left);}if(root->right)     //如果有右孩子,则压栈2{   st1.push(root->right);}}/* 此时栈2的压栈顺序为中右左,取出则为左右中,为后序 */while(!st2.empty())     //循环将栈2中的数据弹出保存到一维数组中{root = st2.top();st2.pop();vec.push_back(root->val);}return vec;             //返回一维数组}
};

http://www.ppmy.cn/news/1427321.html

相关文章

【网站项目】党员之家服务系统小程序

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

OJ:数字三角形(搜索)

&#x1f381;个人主页&#xff1a;我们的五年 &#x1f50d;系列专栏&#xff1a;每日一练 &#x1f337;追光的人&#xff0c;终会万丈光芒 &#x1f337;1.问题描述&#xff1a; ⛳️题目描述&#xff1a; 示出了一个数字三角形。 请编一个程序计算从顶至底的某处的一条路…

Beego框架学习

Beego是一个使用Go语言开发的Web应用框架,它以其高效率和易用性而受到开发者的喜爱。以下是学习Beego框架的一些关键点: 了解Beego的特性:Beego框架支持RESTful和MVC模型,提供了一系列的模块功能,可以帮助开发者快速构建Web应用。它还包含一些高级功能,如监控代码修改进行…

椋鸟数据结构笔记#10:排序·中

文章目录 四、归并排序时间复杂度实现递归实现非递归实现 测试稳定性 五、非比较排序5.1 计数排序时间复杂度实现测试局限性 5.2 桶排序时间复杂度实现测试 5.3 基数排序时间复杂度实现测试局限性 萌新的学习笔记&#xff0c;写错了恳请斧正。 四、归并排序 归并排序是一种非常…

iOS知识点 --- Runtime

Objective-C (OC) 中的 Runtime 原理&#xff1a; Objective-C Runtime 是一套用于支持 Objective-C 动态特性的底层 C 语言 API。它为 Objective-C 提供了以下核心功能&#xff1a; 动态类型&#xff1a;在运行时确定对象的确切类型&#xff0c;允许在程序执行过程中进行类型…

常用node.js命令有哪些呢?

前言 Node.js 是一种在服务器端运行 JavaScript 的开放源代码、跨平台 JavaScript 运行环境。 1、查看当前安装的 Node.js 版本。 node -v 或 node --version 2、查看当前安装的 npm 版本。 npm -v 或 npm --version 3、初始化一个新的 Node.js 项目&#xff0c;会生成一个 pac…

算法学习——LeetCode力扣补充篇11(64. 最小路径和、48. 旋转图像 、169. 多数元素、394. 字符串解码、240. 搜索二维矩阵 II )

算法学习——LeetCode力扣补充篇11 64. 最小路径和 64. 最小路径和 - 力扣&#xff08;LeetCode&#xff09; 描述 给定一个包含非负整数的 m x n 网格 grid &#xff0c;请找出一条从左上角到右下角的路径&#xff0c;使得路径上的数字总和为最小。 说明&#xff1a;每次只…

【C++】飞机大战项目记录

源代码与图片参考自《你好编程》的飞机大战项目&#xff0c;这里不进行展示。 本项目是仅供学习使用的项目 飞机大战项目记录 飞机大战设计报告1 项目框架分析1.1 敌机设计&#xff1a;1.2 玩家飞机控制&#xff1a;1.3 子弹发射&#xff1a;1.4 游戏界面与互动&#xff1a;1.5…