88、二叉树前中后遍历⼿撕代码(递归和⾮递归)
LeetCode 144. ⼆叉树的前序遍历
给你⼆叉树的根节点
示例 1:

例子1:
输⼊:root = [1,null,2,3]
输出:[1,2,3]例子2:
输⼊:root = []
输出:[]例子3:
输⼊:root = [1]
输出:[1]【思路】 由于“中左右”的访问顺序正好符合根结点寻找⼦节点的顺序,因此每次循环时弹栈,输出此弹 栈结点并将其右结点和左结点按照叙述顺序依次⼊栈。⾄于为什么要右结点先⼊栈,是因为栈 后进先出的特性。右结点先⼊栈,就会后输出右结点。
初始化: ⼀开始让root结点先⼊栈,满⾜循环条件
步骤: 弹栈栈顶元素,同时输出此结点 当前结点的右结点⼊栈 当前结点的左结点⼊栈重复上述过程 结束条件: 每次弹栈根结点后⼊栈⼦结点,栈为空时则说明遍历结束。
//递归版
/* 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> ans;
vector<int> preorderTraversal(TreeNode* root) {
// 为空则直接返回
if(root == NULL)
return ans;
ans.push_back(root->val);
preorderTraversal(root->left);
preorderTraversal(root->right);
return ans;
}
}
//⾮递归
class Solution {
public:
std::vector<int>preorderTraversal(TreeNode* root) {
std::vector<int>res;
if (!root) return res;
stack<TreeNode*> st;
TreeNode* node = root;
while (!st.empty() || node) {
while(node) {
st.push(node);
res.push_back(node->val);
node = node->left;
}
node = st.top();
st.pop();
node = node->right;
}
return res;
}
};LeetCode 94. ⼆叉树的中序遍历
难度简单1035
给定⼀个⼆叉树的根节点 root ,返回它的中序遍历。
示例 1:

输⼊:root = [1,null,2,3]
输出:[1,3,2]
示例 2:
输⼊:root = []
输出:[]示例 3:
输⼊:root = [1]
输出:[1]示例 4:

输⼊:root = [1,2]
输出:[2,1]示例 5:

输⼊:root = [1,null,2]
输出:[1,2]【思路】
中序遍历思路相较于前序遍历有很⼤的改变。前序遍历遇到根结点直接输出即可,但中序遍历 “左中右”需先找到此根结点的左结点,因此事实上第⼀个被输出的结点会是整个⼆叉树的最左侧结点。
依据这⼀特性,我们每遇到⼀个结点,⾸先寻找其最左侧的⼦结点,同时⽤栈记录寻找经过的 路径结点,这些是输出最左侧结点之后的返回路径。
之后每次向上层⽗结点返回,弹栈输出上层⽗结点的同时判断此结点是否含有右⼦结点,如果 存在则此右结点⼊栈并到达新的⼀轮循环,对此右结点也进⾏上述操作。 初始化: curr定义为将要⼊栈的结点,初始化为root top定义为栈顶的弹栈结点 步骤:
寻找当前结点的最左侧结点直到curr为空(此时栈顶结点即为最左侧结点)弹栈栈顶结点top并输出 判断top是否具有右结点,如果存在则令curr指向右结点,并在下⼀轮循环入栈
重复上述过程 结束条件:这⾥可以看到结束条件有两个:栈为空, curr为空。这是因为中序遍历优中后右的特性,会有⼀个时刻栈为空但右结点并未被遍历,因此只有在curr也为空证明右结点 不存在的情况下,才能结束遍历。 【代码】
/**
* 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:
// std::vector<int> ret;
// vector<int> inorderTraversal(TreeNode* root) {
// postOrder(root);
// return ret;
// }
// void postOrder(TreeNode* root) {
// if (root == nullptr) return;
// inorderTraversal(root->left);
// ret.push_back(root->val);
// inorderTraversal(root->right);
// }
// };
//迭代法
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
vector<int> ans;
stack<TreeNode*> stk;
TreeNode* curr = root;
while(!stk.empty() || curr != NULL) {
// 找到节点的最左侧节点,同时记录路径⼊栈
while(curr != NULL) {
stk.push(curr);
curr = curr->left;
}
// top 定义是此刻的弹栈元素
TreeNode* top = stk.top();
ans.push_back(top->val);
stk.pop();
// 处理过最左侧结点后,判断其是否存在右⼦树
if(top->right != NULL)
curr = top->right;
}
return ans;
}
};LeetCode 145. ⼆叉树的后序遍历
给定⼀个⼆叉树,返回它的 后序 遍历。
示例:
输⼊: [1,null,2,3]
1
\
2
/
3
输出: [3,2,1]进阶: 递归算法很简单,你可以通过迭代算法完成吗?
【思路】
1、前序遍历的过程是中左右。 2、将其转化成中右左。也就是压栈的过程中优先压⼊左⼦树,再压⼊右⼦树。 3、在弹栈的同时将此弹栈结点压⼊另⼀个栈,完成逆序。 4、对新栈中的元素直接顺序弹栈并输出。
【代码】
/**
* 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> ans;
vector<int> preorderTraversal(TreeNode* root) {
// 为空则直接返回
if(root == NULL)
return ans;
preorderTraversal(root->left);
preorderTraversal(root->right);
ans.push_back(root->val);
return ans;
}
};
*/
//⾮递归版
class Solution {
public:
std::vector<int> postorderTraversal(TreeNode* root) {
std::vector<int> res;
if (!root) return res;
std::stack<TreeNode*> st1;
std::stack<TreeNode*> st2;
st1.push(root);
// 栈⼀顺序存储
while (!st1.empty()){
TreeNode* node = st1.top();
st1.pop();
st2.push(node);
if (node->left) st1.push(node->left);
if (node->right) st1.push(node->right);
}
// 栈⼆直接输出
while (!st2.empty()) {
res.push_back(st2.top()->val);
st2.pop();
}
return res;
}
};Last updated