[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 ...
随机推荐
- SQL点点滴滴_特殊用法笔记
声明: 本文为转载,感谢原作者的辛勤付出. 原博客地址为:http://www.cnblogs.com/icyJ/p/SQL_Statement.html 1.MERGE用法:关联两表,有则改,无则加 ...
- 译文 [ROM][多国语言][2015.06.11] Lenovo S750 (MTK6589) - andrea_d86-lenovos750-4.2.2
************************************************** andrea_d86-lenovos750-4.2.2-150530 ************** ...
- 打通版微社区(5):部署DZ3.2
参考官方帖子http://www.discuz.net/thread-3258186-1-1.html 这是第三方的帖子http://www.discuz.net/thread-3199850-1- ...
- Ionic控件之——按钮(Button)
Ionic提供丰富的按钮特性,足以满足大部分的按钮实现需求. 一.HTML实现一个简单按钮: <button class="button"> 我是按钮 </but ...
- 《C++ Primer Plus》读书笔记之三—循环与关系表达式
第五章 循环与关系表达式 1.表达式是值或者值与操作符的结合,每个C++表达式都有值.表达式到语句的转换只要加一个分号就可以完成.但是,反过来,从语句中删除分号,并不一定能将它转化成表达式. 2.前缀 ...
- 编程题A+B Format的总结(第二次作业<一>)
Github链接地址:https://github.com/Startup-try/object-oriented 这个题目现在想想没有那么难,其实还挺简单的,但是中午花了好长的时间还不懂得怎么做,感 ...
- Java面试基本知识
Java基本知识 基本知识 服务器:Tomcat 支持Servlet jsp JBoss 开源应用服务器 Apache:最广泛的http服务器,只支持静态网页 String是长度不可变,用+=的时候会 ...
- weblogic之CVE-2016-3510反序列化分析
将反序列化的对象封装进了weblogic.corba.utils.MarshalledObject,然后再对MarshalledObject进行序列化,生成payload字节码.由于Marshalle ...
- [Python 多线程] Timer定时器/延迟执行、Event事件 (七)
Timer继承子Thread类,是Thread的子类,也是线程类,具有线程的能力和特征.这个类用来定义多久执行一个函数. 它的实例是能够延迟执行目标函数的线程,在真正执行目标函数之前,都可以cance ...
- Python 模块化 import 语句介绍(一)
用法: import 模块1[,模块2,模块3...] os 顶级模块os.path 非顶级模块as 相当于重命名 import 的本质: 解释器负责模块单独加载,单独初始化,生成一个模块对象,当前作 ...