leetcode 144.二叉树的前序遍历

leetcode 144.二叉树的前序遍历

题干

给定一个二叉树,返回它的 前序 遍历。

示例:
输入: [1,null,2,3]
1

2
/
3
输出: [1,2,3]

在这里插入图片描述

题解

无脑递归

class Solution {
public:
    vector<int> ans;
    void dfs(TreeNode* root){
        if(root!=nullptr){
            ans.push_back(root->val);
            dfs(root->left);
            dfs(root->right);
        }
    }
    vector<int> preorderTraversal(TreeNode* root) {
        dfs(root);
        return ans;
    }
};

同理,可以显式维护一个栈
* 由于栈后进先出所以先入右节点

class Solution {
public:
    vector<int> preorderTraversal(TreeNode* root) {
        if(root==nullptr)
            return {};
        vector<int> ans;
        stack<TreeNode*> tree;
        tree.push(root);
        while(!tree.empty()){
            auto currentNode = tree.top();
            tree.pop();
            ans.push_back(currentNode->val);
            if(currentNode->right != nullptr)
                tree.push(currentNode->right);
            if(currentNode->left !=nullptr)
                tree.push(currentNode->left);
        }
        return ans;
    }
};

morris遍历官方题解我自己注释版

class Solution {
public:
    vector<int> preorderTraversal(TreeNode *root) {
        vector<int> res;
        if (root == nullptr) {
            return res;
        }
        TreeNode *p1 = root, *p2 = nullptr;
        while (p1 != nullptr) {
            //p2为p1的左子节点
            p2 = p1->left;
            //若p2不为空
            if (p2 != nullptr) {
                //寻找以p2为根的树的最右节点(由于p2是p1的左子节点,所以此最右节点即为中序遍历中p1的前驱节点)
                while (p2->right != nullptr && p2->right != p1) {//最右节点没有建立到p1的线索的情况,和已经建立了线索的情况
                    p2 = p2->right;
                }//循环结束后p2为p1的左子树的最右节点

                //若p2的未与p1建立线索
                if (p2->right == nullptr) {
                    //将p1的值推入答案
                    res.emplace_back(p1->val);
                    //建立p2到p1的线索(使用右子节点)
                    p2->right = p1;
                    //继续遍历p1的左子节点
                    p1 = p1->left;
                    continue;
                } else {//若p2的右子节点已与p1建立线索,说明左子树已经被遍历过一次了,直接清空线索,快进到p1 = p1->right开始遍历右子树
                    //清空线索
                    p2->right = nullptr;
                }
            } else {//p1左子节点为空的情况,直接将p1的值推入答案
                res.emplace_back(p1->val);
            }
            //左子节点为空时按照前序遍历的顺序应该开始遍历右子节点了
            p1 = p1->right;
        }
        return res;
    }
};
©️2020 CSDN 皮肤主题: 游动-白 设计师:上身试试 返回首页