递归法

前序遍历

给你二叉树的根节点 root ,返回它节点值的前序 遍历。
示例 1:
输入:root = [1,null,2,3]
输出:[1,2,3]
示例 2:
输入:root = []
输出:[]
示例 3:
输入:root = [1]
输出:[1]
示例 4:
输入:root = [1,2]
输出:[1,2]
示例 5:
输入:root = [1,null,2]
输出:[1,2]
提示:
树中节点数目在范围 [0, 100] 内
-100 <= Node.val <= 100
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/binary-tree-preorder-traversal
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

分析

递归:
1.规定递归的函数的参数和返回值
参数:一个指针TreeNode* cur
返回值:结果是一个数组:vector<int>& vec
2.确定终止条件。深度优先搜索,遇到空指针才停止

if(cur == NULL)
return;

3.确定单层递归的逻辑

vec.push(cur->val);//根
traversal(cur->left,vec);//左
traversal(cur->right,vec);//右

代码

/*** 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:void traversal(TreeNode* cur,vector<int>& vec)//单次遍历的函数{if(cur == NULL)return;vec.push_back(cur->val);traversal(cur->left,vec);traversal(cur->right,vec);}vector<int> preorderTraversal(TreeNode* root) {vector<int> result;traversal(root,result);return result;}
};

中序遍历

代码

/*** 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:void traversal(TreeNode* cur,vector<int>& vec){if(cur == NULL){return;}traversal(cur->left,vec);vec.push_back(cur->val);traversal(cur->right,vec);}vector<int> inorderTraversal(TreeNode* root) {vector<int> result;traversal(root,result);return result;}
};

后序遍历

/*** 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:void traversal(TreeNode* cur,vector<int>& vec){if(cur == NULL)return;traversal(cur->left,vec);traversal(cur->right,vec);vec.push_back(cur->val);}vector<int> postorderTraversal(TreeNode* root) {vector<int> result;traversal(root,result);return result;}
};

迭代法

前序遍历(根左右)

【分析】编程语言中,常用“栈”来实现递归,用迭代法模拟递归也用栈。

代码

/*** 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<int> preorderTraversal(TreeNode* root) {stack<TreeNode*> st;//定义一个栈保存树中的结点vector<int> res;if(root == NULL) return res;st.push(root);//先把根结点放入栈中while(!st.empty()){TreeNode* node = st.top();//树的根节点就是栈顶元素st.pop();//将当前栈顶元素弹出res.push_back(node->val);if(node->right)st.push(node->right);//将栈顶元素的右孩子入栈if(node->left)st.push(node->left);//将栈顶元素的左孩子入栈}//一遍遍历结束,到了左子树的根节点,即上一个结点的左孩子,即此时栈的栈顶元素return res;}
};

后序遍历(左右根)

上文中前序遍历的顺序是:中->左->右
改为:中->右->左
再翻转数组:左->右->中

代码

/*** 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<int> postorderTraversal(TreeNode* root) {stack<TreeNode*> st;vector<int> res;//vector<int> rres;if(root == NULL)return res;st.push(root);while(!st.empty()){TreeNode* node = st.top();st.pop();res.push_back(node->val);if(node->left) st.push(node->left);if(node->right) st.push(node->right);}reverse(res.begin(),res.end());return res;}
};

中序遍历


左孩子为空将栈顶元素加到数组里;右孩子为空,弹出栈顶元素。

模拟例子中的步骤

  • 从根节点开始向左遍历。根节点为5
cur = root;
  • 一直到遍历到最左端,一路向左,将指针经过的所有左结点放入栈中,直到再无左结点可遍历时停止。当栈为空时,也停止遍历。将5、4、1依次放入栈中
while(cur!=NULL || !st.empty())
{if(cur != NULL){st.push(cur);cur = cur->left;}
  • 访问到最左端结点1,1没有左孩子了。取栈顶结点1(即最近访问过的结点),将其弹出栈,加入到数组(加入到数组的结点都是要处理的),遍历此时取出来的栈顶结点1的右孩子
else
{cur = st.top();st.pop();res.push_back(cur->val);cur = cur->right;
}
}
  • 结点1的右孩子也为空,执行的还是else分支,即弹出栈顶元素,此时栈顶元素为4,将4加入数组,处理结点4,4的右孩子为2
  • 此时cur->val=2,执行if分支,将2加入栈中
  • 执发现2的左孩子为空,执行else,弹出栈顶元素2,并加入数组,发现2的右孩子也为空
  • 执行else取此时栈顶元素5,将5加入数组,取5的右孩子6
  • 执行if将6入栈并发现6无左孩子,执行else,将6弹出栈,最终栈空,循环停止,程序结束
    对于第一遍遍历就存在栈中的元素,取出来放到数组中时要做的操作的只有访问右节点,但是若其含有右节点则需要将其右节点从头执行循环,要新加入栈中。即对于不是第一遍遍历就在栈中的节点,会多了个if操作

代码

/*** 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<int> inorderTraversal(TreeNode* root) {vector<int> res;stack<TreeNode*> st;TreeNode* cur = root;while(cur!=NULL || !st.empty()){if(cur!=NULL){st.push(cur);//如果访问到的元素不为空 就把它记录到栈里 即记录指针指过的元素cur = cur->left;//指针一路向左}//遇到了空结点else{cur = st.top();//记录最近访问过的结点 即栈顶元素st.pop();//将其弹出栈 放入数组res.push_back(cur->val);cur = cur->right;//遍历当前指针的右孩子}}return res;}
};

【数据结构与算法】力扣:二叉树的前、中、后序遍历相关推荐

  1. 二叉树的前,中,后序遍历(思路分析) [Java][数据结构]

    二叉树的前,中,后序遍历(思路分析) 前序遍历: 先输出父节点, 再遍历左子树和右子树 中序遍历: 先遍历左子树, 再输出父节点,再遍历右子树 后序遍历: 先遍历左子树,再遍历右子树,最后输出父节点 ...

  2. Java二叉树的前中后序遍历

    Java二叉树的前中后序遍历 1.前序遍历 1.1前序遍历概念 1.2前序遍历习题 2.中序遍历 2.1中序遍历概念 2.2中序遍历习题 3.后续遍历 3.1后序遍历概念 3.2后序遍历习题 大家好, ...

  3. 数据结构之二叉树的前中后序遍历以及层序遍历

    学习目标:读完这篇博客搞定二叉树的前中后序以及层序遍历 首先:你应该明白什么是二叉树,下面这幅图就是一个完全二叉树 其实所谓的二叉树就是一个节点有小于等于二个分支的树,可以没有分支,可以有1条分支,可 ...

  4. 数据结构与算法(java):树-二叉树(二叉查找树(BST)、线索化二叉树、哈夫曼树、平衡二叉树【AVL】、二叉树的前中后序遍历)

    二叉树 1.定义 二叉树 就是度不超过2的树(每个结点最多只有两个子结点).如图 2.特殊二叉树 满二叉树 当二叉树的每一个层的结点树都达到最大值,则这个二叉树就是满二叉树. 完全二叉树 叶结点只能出 ...

  5. 二叉树的前中后序遍历之迭代法(非统一风格迭代方式)

    文章目录 前言 一.前序遍历(迭代法) 二.中序遍历(迭代法) 三.后序遍历(迭代法) 总结 前言 「递归的实现就是:每一次递归调用都会把函数的局部变量.参数值和返回地址等压入调用栈中」,然后递归返回 ...

  6. 二叉树的前中后序遍历(考试常考)

    二叉树遍历的概念 二叉树的遍历是按某种规则对二叉树的每个节点均只被访问一次,根据根节点访问位置的不同分为三种:先序遍历(根左右).中序遍历(左根右).后序遍历(左右根).         由于树是通过 ...

  7. 【数据结构】二叉树的前中后序遍历

    二叉树的三种遍历 1. 创建一棵简单的二叉树 1.1 二叉树结构体实现 1.2 创造一个二叉树结点的函数 1.3 手动创造一棵二叉树 2.为什么要遍历? 3.最重要的知识:由二叉树引出的子问题分析 4 ...

  8. 【Java数据结构】二叉树的前中后序遍历(递归和非递归)

    二叉树的遍历 递归做法 前序遍历 中序遍历 后序遍历 非递归 前序遍历 中序遍历 后序遍历 二叉树遍历是二叉树的一种重要操作 必须要掌握 二叉树的遍历可以用递归和非递归两种做法来实现 递归做法 前序遍 ...

  9. 二叉树的前中后序遍历之迭代法(统一风格迭代方式)

    一.前序遍历(迭代法)->右左中 前序遍历是中左右,每次先处理的是中间节点,那么先将根节点放入栈中,然后将右孩子加入栈,再加入左孩子. 为什么要先加入 右孩子,再加入左孩子呢?因为这样出栈的时候 ...

  10. (必背)二叉树的前中后序遍历(利用栈)

    二叉树的前序遍历(利用栈) 1.首先将根节点压入栈 2.栈中的首元素出栈,然后先将其右节点压入栈中,再将栈中的左节点压入栈中(如果左右节点分别存在的话) 3.重复步骤2直到栈为空 class Solu ...

最新文章

  1. Linux下互斥量与条件变量详细解析
  2. 转载:T-SQL语句大全
  3. Node.js做的代理转发服务器
  4. selenium2与python自动化1-selenium简介与降级
  5. window.onload,body onload=function(), document.onreadystatechange, httpRequest.onreadystatechang
  6. Mysql连接失败报Received fatal alert: protocol_version问题解决
  7. @NOIP2018 - D1T1@ 铺设道路
  8. 激光雷达点云数据处理
  9. linux gns3使用教程,《GNS3实战指南》——2.4 在Ubuntu Linux上安装
  10. 鸿蒙os正式版推送时间,鸿蒙OS正式版推送时间确定,游戏性能更强,流畅度稳定性均提升...
  11. 修改element ui tree 搜索功能,实现分级搜索,关键字高亮
  12. 新版本android_id,android手机唯一id方案总结
  13. coco数据集百度网盘下载
  14. Pytorch中 nn.Transformer的使用详解与Transformer的黑盒讲解
  15. 新程序员001:开发者黄金十年
  16. Xilinx_RAM_IP核的使用
  17. 文心一言 VS 讯飞星火 VS chatgpt (19)-- go语言的slice和rust语言的Vec的扩容流程是什么?
  18. C语言学生成绩管理系统运行退不出来,哭诉、拜求C语言学生成绩管理系统
  19. Linux下Matlab+CUDA双显卡环境搭建(核显+独显)
  20. Cache 和 Buffer 都是缓存,主要区别是什么?

热门文章

  1. Nginx篇之实现反向代理和端口转发
  2. Knative部署应用以及应用的更新、应用的分流(二)
  3. 集合中所有子集元素之和
  4. egg html模板,egg(35,36)--egg实现项目的静态模板
  5. 不良资产评估 难点与问题分析
  6. 刷题_33:剪花布条 and 客似云来
  7. SOP运营场景与流程介绍
  8. b丅151组成的充电器电路_1V/24V电子充电器原理与维修
  9. 少儿英语-思维导图学语法-特殊名词变复数
  10. 算生日(贼快的算法)