LeetCode 144 ——二叉树的前序遍历
1. 题目

2. 解答
2.1. 递归法
定义一个存放树中数据的向量 data,从根节点开始,如果节点不为空,那么
- 将当前节点的数值加入到 data 中
- 递归得到其左子树的数据向量 temp,将 temp 合并到 data 中去
- 递归得到其右子树的数据向量 temp,将 temp 合并到 data 中去
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<int> preorderTraversal(TreeNode* root) {
vector<int> data = {};
vector<int> temp = {};
if (root != NULL)
{
data.push_back(root->val);
temp = preorderTraversal(root->left);
data.insert(data.end(),temp.begin(),temp.end());
temp = preorderTraversal(root->right);
data.insert(data.end(),temp.begin(),temp.end());
}
return data;
}
};
2.2. 迭代法
定义一个存放树中节点的栈 node_stack 和存放数据的向量 data,从根节点开始,如果节点不为空或者栈非空,循环以下过程:
- 如果节点非空,将节点的值加入 data,如果节点有右孩子,将节点右孩子压入栈,节点指向其左孩子,循环直到节点为空
- 如果节点为空,栈非空,则弹出栈顶节点
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<int> preorderTraversal(TreeNode* root) {
vector<int> data = {};
stack<TreeNode*> node_stack;
TreeNode* temp = root;
while (temp || !node_stack.empty())
{
while(temp != NULL)
{
data.push_back(temp->val);
if (temp->right) node_stack.push(temp->right);
temp = temp->left;
}
// 若最后一个节点没有右子节点,栈为空
if (!node_stack.empty()) // 栈非空
{
temp = node_stack.top();
node_stack.pop();
}
}
return data;
}
};
2.3. Morris 遍历法
前面两种方法要么需要函数栈要么需要人工栈,其空间复杂度为 \(O(n)\),而 Morris 遍历法可以做到在不影响时间复杂度的情况下做到空间复杂度为 \(O(1)\)。
定义一个存放数据的向量 data,从根节点开始,如果当前节点非空,循环以下过程:
- 如果当前节点没有左孩子,将当前节点的值加入到 data 中,当前节点指向其右孩子
- 如果当前节点有左孩子,则寻找当前节点的前驱节点,即节点值小于该节点值并且值最大的节点,也即当前节点左子树中值最大的节点
- a) 如果前驱节点没有右孩子,前驱节点右孩子指向当前节点,将当前节点的值加入到 data 中,当前节点指向其左孩子
- b) 如果前驱节点右孩子为当前节点,当前节点指向其右孩子,前驱节点右孩子设为空(恢复原有树结构)

/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<int> preorderTraversal(TreeNode* root) {
vector<int> data = {};
TreeNode* cur = root;
TreeNode* pre = NULL;
while (cur)
{
if (cur->left == NULL)
{
data.push_back(cur->val);
cur = cur->right;
}
else
{
// 寻找前驱结点
pre = cur->left;
while (pre->right != cur && pre->right)
{
pre = pre->right;
}
if (pre->right == NULL)
{
data.push_back(cur->val);
pre->right = cur;
cur = cur->left;
}
else
{
cur = cur->right;
pre->right = NULL;
}
}
}
return data;
}
};
获取更多精彩,请关注「seniusen」!

LeetCode 144 ——二叉树的前序遍历的更多相关文章
- LeetCode 144. 二叉树的前序遍历(Binary Tree Preorder Traversal)
144. 二叉树的前序遍历 144. Binary Tree Preorder Traversal 题目描述 给定一个二叉树,返回它的 前序 遍历. LeetCode144. Binary Tree ...
- Java实现 LeetCode 144 二叉树的前序遍历
144. 二叉树的前序遍历 给定一个二叉树,返回它的 前序 遍历. 示例: 输入: [1,null,2,3] 1 \ 2 / 3 输出: [1,2,3] /** * Definition for a ...
- Leetcode 144.二叉树的前序遍历
1.题目描述 给定一个二叉树,返回它的 前序 遍历. 示例: 输入: [1,null,2,3] 1 \ 2 / 3 输出: [1,2,3] 进阶: 递归算法很简单,你可以通过迭代算法完成吗? 2.解法 ...
- 【leetcode 144. 二叉树的前序遍历】解题报告
前往二叉树的:前序,中序,后序 遍历算法 方法一:递归 vector<int> res; vector<int> preorderTraversal(TreeNode* roo ...
- LeetCode 144. 二叉树的前序遍历(Binary Tree Preorder Traversal)
题目描述 给定一个二叉树,返回它的 前序 遍历. 示例: 输入: [1,null,2,3] 1 \ 2 / 3 输出: [1,2,3] 进阶: 递归算法很简单,你可以通过迭代算法完成吗? 解题思路 由 ...
- LeetCode 144. 二叉树的前序遍历 (非递归)
题目链接:https://leetcode-cn.com/problems/binary-tree-preorder-traversal/ 给定一个二叉树,返回它的 前序 遍历. /** * Defi ...
- LeetCode:二叉树的前序遍历【144】
LeetCode:二叉树的前序遍历[144] 题目描述 给定一个二叉树,返回它的 前序 遍历. 示例: 输入: [1,null,2,3] 1 \ 2 / 3 输出: [1,2,3] 题目分析 如果用递 ...
- 【LeetCode】144. 二叉树的前序遍历
144. 二叉树的前序遍历 知识点:二叉树:递归:Morris遍历 题目描述 给你二叉树的根节点 root ,返回它节点值的 前序 遍历. 示例 输入:root = [1,null,2,3] 输出:[ ...
- Leetcode(144)-二叉树的前序遍历
给定一个二叉树,返回它的 前序 遍历. 示例: 输入: [1,null,2,3] 1 \ 2 / 3 输出: [1,2,3] 进阶: 递归算法很简单,你可以通过迭代算法完成吗? 二叉树的前序遍历有递归 ...
随机推荐
- ubuntu包管理机制
1 ubuntu包管理机制 跟大家分享一下ubuntu的软件管理机制.如果你们有过: apt-get install 或者 apt-get update 失败的经历. 在众多的apt命令中迷失. 疑惑 ...
- C++分享笔记:5X5单词字谜游戏设计
笔者在大学二年级刚学完C++程序设计后,做过一次课程设计,题目是:5X5单词字谜游戏设计.为了设计算法并编写程序,笔者在当时颇费了一番心力,最后还是成功地完成了.设计中不乏有精妙之处.该程序设计完全是 ...
- spark源码编译记录
spark在项目中已经用了一段时间了,趁现在空闲,下个源码编译在IDEA里面阅读下,特此记录过程. 前提已经安装maven和git 1.上官网下载源码的包: 2.然后解压到一个文件夹 3.编译,编译的 ...
- opencv3 学习一 - Visual Studio 配置
Step 1 下载最新版的Opencv3.4.2,见图片中的网址,选择 Win Pack. Step 2 安装Opencv3 到指定目录,见图片,路径后面会用到. Step 3 把安装目录下的bin路 ...
- socketpair通信
1.线程间通信(参考安卓源码InputTransport.cpp) #include <pthread.h> #include <sys/types.h> /* See NOT ...
- openssl windows平台编译库
首先感谢http://blog.csdn.net/YAOJINGKAO/article/details/53041165?locationNum=10&fps=1和https://www.cn ...
- Redis 常用数据结构命令
1. 字符串(string) 增加元素 set key value [EX seconds] [PX milliseconds] [NX|XX] EX seconds:为键设置秒级过期时间 PX mi ...
- 北京Uber优步司机奖励政策(3月26日)
滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...
- 每天看一片代码系列(三):codepen上一个音乐播放器的实现
今天我们看的是一个使用纯HTML+CSS+JS实现音乐播放器的例子,效果还是很赞的: codePen地址 HTML部分 首先我们要思考一下,一个播放器主要包含哪些元素.首先要有播放的进度信息,还有播放 ...
- 相机imu外参标定
1. 第一步初始化imu外参(可以从参数文档中读取,也可以计算出),VINS中处理如下: # Extrinsic parameter between IMU and Camera. estimate_ ...