力扣 144,94,145 二叉树前中后序遍历 [递归,Morris]
二叉树不同遍历介绍
请查看这里
144. 二叉树的前序遍历
给你二叉树的根节点 root
,返回它节点值的 前序 遍历。
示例 1:
输入:root = [1,null,2,3]
输出:[1,2,3]
递归
使用递归,每次都首先记录val
,再按先左后右的顺序进入递归。
查看代码
/**
* 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:
void work(TreeNode* root,vector<int>& t){
if(!root)
return;
t.push_back(root->val);
if(root->left)
work(root->left,t);
if(root->right)
work(root->right,t);
}
vector<int> preorderTraversal(TreeNode* root) {
vector<int> t;
work(root,t);
return t;
}
};
迭代
递归的流程就是深度遍历,先放进去的节点反而会最后访问,和栈的思想一样,
递归实质是使用系统栈,那我们可以直接使用栈来模拟递归的流程,
注意递归时先左后右,可是使用栈,因为先进后出,所以需要先右后左。
查看代码
/**
* 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> preorderTraversal(TreeNode* root) {
vector<int> t;
stack<TreeNode*> st;
if(!root)
return t;
st.push(root);
while(!st.empty()){
TreeNode* cur=st.top();
st.pop();
t.push_back(cur->val);
if(cur->right)
st.push(cur->right);
if(cur->left)
st.push(cur->left);
}
return t;
}
};
Morris遍历
Morris遍历的介绍在这里。
查看代码
/**
* 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> preorderTraversal(TreeNode* root) {
vector<int> res;
TreeNode *curr = root;
while (curr != NULL)
{
if (curr->left == NULL)
{
res.emplace_back(curr->val);//输出当前节点
curr = curr->right;
}
else
{
// 找当前节点的前趋结点
TreeNode* predecessor = curr->left;
while (predecessor->right != NULL&& predecessor->right != curr)
{
predecessor = predecessor->right;
}
// 使当前节点成为inorder的前序节点的右侧子节点
if (predecessor->right == NULL)
{
predecessor->right = curr;
res.emplace_back(curr->val);//输出当前节点
curr = curr->left;
}
//复原之前的修改
else
{
predecessor->right = NULL;
curr = curr->right;
}
}
}
return res;
}
};
94. 二叉树的中序遍历
给定一个二叉树的根节点 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:
void work(TreeNode* root,vector<int> &t){
if(!root)
return;
if(root->left)
work(root->left,t);
t.push_back(root->val);
if(root->right)
work(root->right,t);
}
vector<int> inorderTraversal(TreeNode* root) {
vector<int> t;
work(root,t);
return t;
}
};
Morris
Morris
/**
* 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> inorderTraversal(TreeNode* root) {
vector<int> res;
TreeNode *curr = root;
while (curr != NULL)
{
if (curr->left == NULL)
{
res.emplace_back(curr->val);//输出当前节点
curr = curr->right;
}
else
{
// 找当前节点的前趋结点
TreeNode* predecessor = curr->left;
while (predecessor->right != NULL
&& predecessor->right != curr)
{
predecessor = predecessor->right;
}
// 使当前节点成为inorder的前序节点的右侧子节点
if (predecessor->right == NULL)
{
predecessor->right = curr;
curr = curr->left;
}
//复原之前的修改
else
{
predecessor->right = NULL;
res.emplace_back(curr->val);//输出当前节点
curr = curr->right;
}
}
}
return res;
}
};
145. 二叉树的后序遍历
给你一棵二叉树的根节点 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:
void work(TreeNode* root,vector<int>& t){
if(!root)
return;
if(root->left)
work(root->left,t);
if(root->right)
work(root->right,t);
t.push_back(root->val);
}
vector<int> postorderTraversal(TreeNode* root) {
vector<int> t;
work(root,t);
return t;
}
};
Morris
后序
/**
* 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> postorderTraversal(TreeNode* root) {
TreeNode* node = root;
vector<int> res;//需要有一个遍历存储路径,当然也可以用vector存储,然后翻转
while(node) {
if(!node->right) {//这里就不需要输出了
res.emplace_back(node->val);//
node = node->left;
}
else {
TreeNode* prev = node->right;//predecessor
while(prev->left && prev->left != node)//这里与preorder相反
prev = prev->left;
if(!prev->left) {//同上
prev->left = node;
res.emplace_back(node->val);//
node = node->right;
}
else {//同上
node = node->left;
prev->left = NULL;
}
}
}
reverse(res.begin(),res.end());
return res;
}
};