[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 ...
随机推荐
- 【源代码R3】移植一份LARGE_INTEGER转时间的代码
本代码来自ReactOS-0.4.0\lib\rtl\time.c中的函数RtlTimeToTimeFields(IN PLARGE_INTEGER Time, OUT PTIME_FIELDS Ti ...
- Java设计模式—备忘录模式
个人感觉备忘录模式是一个比较难的设计模式,备忘录模式就是一个对象的备份模式,提供了一种程序数据的备份方法. 定义如下:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态.这样以 ...
- 【javascript】javascript设计模式之工厂模式
1.要解决的问题 2.如何实现 3.与构造函数的区别 4.总结 1.要解决的问题 工厂模式通常用于重复创建相似对象,提供动态创建对象的接口. 2.工厂模式最为设计模式中构造模式之一,通常在类或类的静态 ...
- 辅助判卷程序的一些小bug
首先谈一下,double类型 之前查过一些资料,double类型做==(相等)判断时候,会出现一些错误,及61.95与61.95不相等 对main函数中的部分加以改正,下面的answer为string ...
- python 描述符 上下文管理协议 类装饰器 property metaclass
1.描述符 #!/usr/bin/python env # coding=utf-8 # 数据描述符__get__ __set__ __delete__ ''' 描述符总结 描述符是可以实现大部分py ...
- vue2.0中的计算属性
计算属性是一个很邪门的东西,只要在它的函数里引用了data中的某个属性,当这个属性发生变化的时候,函数仿佛可以嗅探到这个变化,并自动重新执行. 上代码会源源不断的打印出a的值.如果希望b依赖data中 ...
- 修改maven默认的jdk版本
修改maven默认的jdk版本,想改彻底需要在maven的全局配文件(settings.xml)增加以下信息: 在profiles 节点下增加: <profile> <id> ...
- String,StringBuffer和StringBuilder三者的讲解
对于java的学习者而言,无论是初学者,还是java大师,String对于大家而言,也绝对不会陌生.下面本人就从 自己学习的角度大致分析一下String,StringBuffer和StringBui ...
- laravel middleware
当你使用larvel创建一个相对比较复杂的web网站时,往往你的routes文件就会变得很庞大.一般来说在开始网站编码之前,最好做一个整体规划,把这些route逻辑上划分为不同的group,每一个gr ...
- 排查 Azure 虚拟机的远程桌面连接问题
与基于 Windows 的 Azure 虚拟机 (VM) 的远程桌面协议 (RDP) 连接可能会因各种原因而失败,使用户无法访问 VM. 问题可能出在 VM 上的远程桌面服务.网络连接或主计算机上的远 ...