算法训练1-day11-二叉树

25 阅读2分钟

今天是二叉树

  1. 144. 二叉树的前序遍历

AC代码:

//递归
class Solution {
public:
    vector<int> preorderTraversal(TreeNode* root) {
        vector<int> ans;
        preorder(root, ans);
        return ans;
    }

    void preorder(TreeNode* root, vector<int>& ans) {
        if (root == nullptr)
            return;

        ans.push_back(root->val);
        preorder(root->left, ans);
        preorder(root->right, ans);
    }
};
//迭代
class Solution {
public:
    vector<int> preorderTraversal(TreeNode* root) {
        vector<int> ans;
        if(root == nullptr) return ans;
        stack<TreeNode*> nodes;
        nodes.push(root);
        while(!nodes.empty()){
            TreeNode* node = nodes.top();
            nodes.pop();
            ans.push_back(node->val);

            if(node->right != nullptr) nodes.push(node->right);
            if(node->left != nullptr) nodes.push(node->left);
        }

        return ans;
    }
};
  1. 145. 二叉树的后序遍历

AC代码:

//递归
class Solution {
public:
    vector<int> postorderTraversal(TreeNode* root) {
        vector<int> ans;
        postorder(root, ans);
        return ans;
    }

    void postorder(TreeNode* root, vector<int>& ans) {
        if (root == nullptr)
            return;

        postorder(root->left, ans);
        postorder(root->right, ans);
        ans.push_back(root->val);
    }
};
//迭代
class Solution {
public:
    vector<int> postorderTraversal(TreeNode* root) {
        vector<int> ans;
        if(root == nullptr) return ans;
        stack<TreeNode*> nodes;
        nodes.push(root);
        while(!nodes.empty()){
            TreeNode* node = nodes.top();
            nodes.pop();
            ans.push_back(node->val);

            if(node->left != nullptr) nodes.push(node->left);
            if(node->right != nullptr) nodes.push(node->right);
        }

        reverse(ans.begin(), ans.end());
        return ans;
    }
};
  1. 94. 二叉树的中序遍历

AC代码:

class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int> ans;
        inorder(root, ans);
        return ans;
    }

    void inorder(TreeNode* root, vector<int>& ans) {
        if (root == nullptr)
            return;

        inorder(root->left, ans);
        ans.push_back(root->val);
        inorder(root->right, ans);
    }
};
//迭代
class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int> ans;
        if (root == nullptr) return ans;
        stack<TreeNode*> nodes;
        TreeNode* node = root;
        while (node != nullptr || !nodes.empty()) {
            if (node != nullptr) {
                nodes.push(node);
                node = node->left; //左
            } else {
                node = nodes.top();
                nodes.pop();
                ans.push_back(node->val); //中
                node = node->right; //右
            }
        }
        return ans;
    }
};

统一迭代法

核心思想是用一个标记来表示当前节点是否可以记录,有两种方法

  1. 在节点入栈时,用一个空指针来表示下一次这个节点可以进行处理记录
  2. 额外记录一个bool信息,为true表示下一次访问时可以进行处理
class Solution {
public:
    vector<int> preorderTraversal(TreeNode* root) {
        vector<int> ans;
        if (root == nullptr) return ans;
        stack<pair<TreeNode*, bool>> nodes;
        nodes.push(make_pair(root, false));
        while (!nodes.empty()) {
            auto item = nodes.top();
            TreeNode* node = item.first;
            bool visited = item.second;
            nodes.pop();
            if (visited) {
                ans.push_back(node->val);
                continue;
            }

            // 重新安排顺序,前序遍历:中左右,stack中顺序就是倒过来
            if (node->right != nullptr) 
	            nodes.push(make_pair(node->right, false)); // 右
            if (node->left != nullptr) 
	            nodes.push(make_pair(node->left, false)); // 左
            nodes.push(make_pair(node, true)); // 中
            
            //如果是中序遍历:左中右,就需要改变入栈的顺序为右中左:
            //if (node->right != nullptr) 
	        //    nodes.push(make_pair(node->right, false)); // 右
            //nodes.push(make_pair(node, true)); // 中
            //if (node->left != nullptr) 
            //    nodes.push(make_pair(node->left, false)); // 左
        }

        return ans;
    }
};
  1. 102. 二叉树的层序遍历
class Solution {
public:
    vector<vector<int>> levelOrder(TreeNode* root) {
        vector<vector<int>> ans;
        if (root == nullptr) return ans;

        queue<TreeNode*> nodes;
        nodes.push(root);
        while (!nodes.empty()) {
            int n = nodes.size();
            vector<int> layerNodes(n);
            for (int i = 0; i < n; ++i) {
                TreeNode* node = nodes.front();
                nodes.pop();
                layerNodes[i] = node->val;

                if (node->left != nullptr) nodes.push(node->left);
                if (node->right != nullptr) nodes.push(node->right);
            }
            ans.push_back(layerNodes);
        }

        return ans;
    }
};