[leetcode] 二叉树的前序,中序,后续,层次遍历
前序遍历
[144] Binary Tree Preorder Traversal
递归遍历
使用递归,先保存父节点的值,再对左子树进行遍历(递归),最后对右子树进行遍历(递归)
vector<int> preorderTraversal(TreeNode* root) {
vector<int> re;
preTraversal(root, re);
return re;
}
void preTraversal(TreeNode* root, vector<int>& re)
{
if (!root)
{
return;
}
re.push_back(root->val);
preTraversal(root->left, re);
preTraversal(root->right, re);
}
非递归遍历
方法一: 使用一个辅助栈(利用栈的后进先出的特性),先一直找左子树直到左子树为null(此过程中将遍历到的节点的值保存并且将这些节点压入栈中)。再弹出栈顶元素,对其右子树再做以上操作。直到栈为空。
vector<int> preorderTraversal(TreeNode* root)
{
vector<int> vec;
stack<TreeNode*> st;
while (root or !st.empty())
{
while (root)
{
vec.push_back(root->val);
st.push(root);
root = root->left;
}
if (!st.empty())
{
auto temp = st.top();
st.pop();
root = temp->right;
}
}
return vec;
}
方法二:
使用一个辅助栈来完成(利用栈的后进先出的特性)。先将父节点的值保存,然后将右子树压入栈中,再将左子树压入栈中(注意顺序,要保证出栈的时候左子树在右子树先)。再对栈顶元素进行上述操作。直到栈为空。
vector<int> postorderTraversal(TreeNode* root) {
vector<int> re;
if (!root)
{
return re;
}
stack<TreeNode*> st;
st.push(root);
while (!st.empty())
{
auto tmp = st.top();
re.push_back(tmp->val);
st.pop();
if (tmp->left)
{
st.push(tmp->left);
}
if (tmp->right)
{
st.push(tmp->right);
}
}
reverse(re.begin(), re.end());
return re;
}
中序遍历
[94] Binary Tree Inorder Traversal
递归遍历
使用递归,再对左子树进行遍历(递归),先保存父节点的值,最后对右子树进行遍历(递归)
vector<int> inorderTraversal(TreeNode* root) {
vector<int> re;
inTraversal(root, re);
return re;
}
void inTraversal(TreeNode* root, vector<int>& re)
{
if (!root)
{
return;
}
inTraversal(root->left, re);
re.push_back(root->val);
inTraversal(root->right, re);
}
非递归遍历
后前序遍历思路一致,只是保存值的地方改变了。在节点出栈的时候再保存值,这样可以实现先保存左子树的值再保存父节点的值。
vector<int> inorderTraversal(TreeNode* root)
{
vector<int> vec;
stack<TreeNode*> st;
while (root or !st.empty())
{
while (root)
{
st.push(root);
root = root->left;
}
if (!st.empty())
{
auto temp = st.top();
vec.push_back(temp->val);
st.pop();
root = temp->right;
}
}
return vec;
}
后序遍历
[145] Binary Tree Postorder Traversal
递归遍历
使用递归,再对左子树进行遍历(递归),再对右子树进行遍历(递归),最后先保存父节点的值
vector<int> postorderTraversal(TreeNode* root) {
vector<int> re;
traversal(root, re);
return re;
}
void traversal(TreeNode* root, vector<int>& re)
{
if (!root)
{
return;
}
traversal(root->left, re);
traversal(root->right, re);
re.push_back(root->val);
}
非递归遍历
前序遍历:根-左-右
后续遍历:左-右-根
可以看到,在前序遍历的时候先遍历右子树再遍历左子树那么顺序就变成了根-右-左,再翻转就变成了后续遍历 左-右-根。根据此思路我们可以先对前序遍历的非递归遍历方法二进行一点点改造,再把结果翻转,就得到了后续遍历的非递归遍历的结果
vector<int> postorderTraversal(TreeNode* root) {
vector<int> re;
if (!root)
{
return re;
}
stack<TreeNode*> st;
st.push(root);
while (!st.empty())
{
auto tmp = st.top();
re.push_back(tmp->val);
st.pop();
if (tmp->left)
{
st.push(tmp->left);
}
if (tmp->right)
{
st.push(tmp->right);
}
}
reverse(re.begin(), re.end());
return re;
}
层次遍历
[102] Binary Tree Level Order Traversal
使用一个辅助队列(利用队列的先进先出特性)。将根节点压入队列中,获取当前队列大小,对当前队列中的所有节点进行遍历,保存其值,若其左右子树非空,则将其入队。直到队列为空为止。
vector<vector<int>> levelOrder(TreeNode* root) {
queue<TreeNode*> qu;
vector<vector<int>> re;
qu.push(root);
while (!qu.empty() and root)
{
vector<int> tmp;
int size = qu.size();
for (int i = ; i < size; ++i)
{
auto ele = qu.front();
qu.pop();
tmp.push_back(ele->val);
if (ele->left)
{
qu.push(ele->left);
}
if (ele->right)
{
qu.push(ele->right);
}
}
re.push_back(tmp);
}
return re;
}
[leetcode] 二叉树的前序,中序,后续,层次遍历的更多相关文章
- hihocoder(第十周)二叉树(前序中序推后续)递推实现
题目 : 后序遍历 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 在参与过了美食节之后,小Hi和小Ho在别的地方又玩耍了一阵子,在这个过程中,小Ho得到了一个非常有意思 ...
- Java 重建二叉树 根据前序中序重建二叉树
题目:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2, ...
- PAT甲题题解-1064. Complete Binary Search Tree (30)-中序和层次遍历,水
由于是满二叉树,用数组既可以表示父节点是i,则左孩子是2*i,右孩子是2*i+1另外根据二分搜索树的性质,中序遍历恰好是从小到大排序因此先中序遍历填充节点对应的值,然后再层次遍历输出即可. 又是一道遍 ...
- Python实现二叉树的前序、中序、后序、层次遍历
有关树的理论部分描述:<数据结构与算法>-4-树与二叉树: 下面代码均基于python实现,包含: 二叉树的前序.中序.后序遍历的递归算法和非递归算法: 层次遍历: 由前序序列.中 ...
- Construct Binary Tree from Preorder and Inorder Traversal(根据前序中序构建二叉树)
根据前序中序构建二叉树. 1 / \ 2 3 / \ / \ 4 5 6 7对于上图的树来说, index: 0 1 2 3 4 5 6 先序遍历为: 6 3 7为了清晰表示,我给节点上了颜色,红色是 ...
- 数据结构实习 - problem K 用前序中序建立二叉树并以层序遍历和后序遍历输出
用前序中序建立二叉树并以层序遍历和后序遍历输出 writer:pprp 实现过程主要是通过递归,进行分解得到结果 代码如下: #include <iostream> #include &l ...
- 算法进阶面试题03——构造数组的MaxTree、最大子矩阵的大小、2017京东环形烽火台问题、介绍Morris遍历并实现前序/中序/后序
接着第二课的内容和带点第三课的内容. (回顾)准备一个栈,从大到小排列,具体参考上一课.... 构造数组的MaxTree [题目] 定义二叉树如下: public class Node{ public ...
- 【美国血统 American Heritage 题解】已知前序中序 求后序
题目: 题目名称:美国血统 American Heritage 题目来源:美国血统 American Heritage ## 题目描述 农夫约翰非常认真地对待他的奶牛们的血统.然而他不是一个真正优秀的 ...
- Tree Recovery(前序中序求后序)
Tree Recovery Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 14640 Accepted: 9091 De ...
- 前序+中序->后序 中序+后序->前序
前序+中序->后序 #include <bits/stdc++.h> using namespace std; struct node { char elem; node* l; n ...
随机推荐
- Class.forName和ClassLoader.loadClass的区别(转载)
Class的装载分了三个阶段,loading,linking和initializing,分别定义在The Java Language Specification的12.2,12.3和12.4.Clas ...
- Http请求超时的一种处理方法
URLConnection类常见的超时处理就是调用其setConnectTimeout和setReadTimeout方法: setConnectTimeout:设置连接主机超时(单位:毫秒) setR ...
- Android GridView显示SD卡的图片
GridView的XML布局: main.xml: <GridViewxmlns:android="http://schemas.android.com/apk/res/android ...
- Android解析WindowManagerService(二)WMS的重要成员和Window的添加过程
前言 在本系列的上一篇文章中,我们学习了WMS的诞生,WMS被创建后,它的重要的成员有哪些?Window添加过程的WMS部分做了什么呢?这篇文章会给你解答. 1.WMS的重要成员 所谓WMS的重要成员 ...
- IEC62304-2006解读
IEC62304强调医疗软件在明确和满足其预期用途的前提下,不能引发不可接受的风险 62304提供一个医疗软件开发的框架,并指出框架下每个过程的要求,62304将过程分解为若干活动,活动分解为若干任务 ...
- day04之VUE痛悟
vue组件组件分为三部分
- 用Appium让Android功能自动化测试飞起来
前言 做Android端功能自动化已有2年多的时间了,使用过的功能自动化框架有Robotium.Uiautomator.Appium.最近研究自动化case复用的方案,调研了Appium的自动化框架, ...
- springDataJpa学习笔记
目录 前言 springData 准备 引用 xml配置初始化JPA pojo dao层接口 使用 新增.修改:save 删除 查询所有 根据ID查询findById 命名规则查询(条件查询) 自定义 ...
- Java常见错误列表
Java常见错误列表: 找不到符号(symbol) 类X是public的,应该被声明在名为X.java的文件中 缺失类.接口或枚举类型 缺失X 缺失标识符 非法的表达式开头 类型不兼容 非法的方法声明 ...
- Linux中脚本的使用方法
Linux中脚本的使用方法 一.前言 关于Linux中的脚本的用法,一直没有时间去好好地总结,正好今天下雨,就好好的整理一下思路吧,其实精通了一门语言,比如C语言,学习其他语言需要的成本是非常少的,同 ...