代码随想录算法训练营第24天(补第12天)| 递归遍历,迭代遍历,统一迭代

前置知识

二叉树的定义:

struct BNode{
  int val;
  BNode* lchild;
  BNode* rchild;
  BNode():lchild(NULL),rchild(NULL){}
  BNode(int val){
    val=val;
    lchild=rchild=NULL;
  }
};

递归遍历

文章链接:https://programmercarl.com/二叉树的递归遍历.html#思路
题目链接:https://leetcode.cn/problems/binary-tree-preorder-traversal/description/
https://leetcode.cn/problems/binary-tree-postorder-traversal/description/
https://leetcode.cn/problems/binary-tree-inorder-traversal/description/

前序遍历:

class Solution {
public:
    void traversal(TreeNode* cur,vector<int>& res){
        if(cur==NULL) return;
        res.push_back(cur->val);
        traversal(cur->left,res);
        traversal(cur->right,res);
    }
    vector<int> preorderTraversal(TreeNode* root) {
        vector<int> res;
        traversal(root,res);
        return res;
    }
};

后续遍历:

class Solution {
public:
    void traversal(TreeNode* cur,vector<int>& res){
        if(cur==NULL) return;
        traversal(cur->left,res);
        traversal(cur->right,res);
        res.push_back(cur->val);
    }
    vector<int> postorderTraversal(TreeNode* root) {
        vector<int> res;
        traversal(root,res);
        return res;
    }
};

中序遍历:

class Solution {
public:
    void traversal(TreeNode* cur,vector<int>& res){
        if(cur==NULL) return;
        traversal(cur->left,res);
        res.push_back(cur->val);
        traversal(cur->right,res);
    }
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int> res;
        traversal(root,res);
        return res;
    }
};

迭代遍历

文章链接:https://programmercarl.com/二叉树的迭代遍历.html#算法公开课
题目链接:https://leetcode.cn/problems/binary-tree-preorder-traversal/description/
https://leetcode.cn/problems/binary-tree-inorder-traversal/description/
https://leetcode.cn/problems/binary-tree-postorder-traversal/description/

前序遍历:

class Solution {
public:
    vector<int> preorderTraversal(TreeNode* root) {
        stack<TreeNode*> st;
        vector<int> res;
        if(root==NULL) return res;
        else st.push(root);
        while(!st.empty()){
            TreeNode* node=st.top();
            st.pop();
            res.push_back(node->val);
            if(node->right) st.push(node->right);
            if(node->left) st.push(node->left);
        }
        return res;
    }
};

中序遍历:由于访问顺序和处理顺序不一样,所以会稍微复杂。需要先用指针访问到树的最后一层再进行处理。

class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int> res;
        stack<TreeNode*> st;
        TreeNode* cur=root;
        while(cur!=NULL||!st.empty()){
            //一直遍历到底部再进行处理
            while(cur!=NULL){
                st.push(cur);
                cur=cur->left;//左
            }
            //可以开始处理了
            if(!st.empty()){
                cur=st.top();  //中
                st.pop();
                res.push_back(cur->val);
                cur=cur->right;  //右
            }
        }
        return res;
    }
};

后序遍历:
可以按照这个思路写:

class Solution {
public:
    vector<int> postorderTraversal(TreeNode* root) {
        vector<int> res;
        stack<TreeNode*> st;
        if(root==NULL) return res;
        else st.push(root);
        while(!st.empty()){
            TreeNode* node=st.top();
            st.pop();
            res.push_back(node->val);
            if(node->left) st.push(node->left);
            if(node->right) st.push(node->right);
        }
        reverse(res.begin(),res.end());
        return res;
    }
};

统一迭代

文章链接:https://programmercarl.com/二叉树的统一迭代法.html
题目链接:https://leetcode.cn/problems/binary-tree-preorder-traversal/description/
https://leetcode.cn/problems/binary-tree-inorder-traversal/description/
https://leetcode.cn/problems/binary-tree-postorder-traversal/description/

要点:使用栈的话,无法同时解决访问节点(遍历节点)和处理节点(将元素放进结果集)不一致的情况。
那我们就将访问的节点放入栈中,把要处理的节点也放入栈中但是要做标记。
如何标记呢,就是要处理的节点放入栈之后,紧接着放入一个空指针作为标记。 这种方法也可以叫做标记法

中序:

class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {
        stack<TreeNode*> st;
        vector<int> res;
        if(root!=NULL) st.push(root);
        while(!st.empty()){
            TreeNode*node=st.top();
            //如果所取的头部节点不为空,就弹出
            if(node!=NULL){
                st.pop();
                if(node->right) st.push(node->right); //右
                st.push(node); //已经弹出的中间节点继续压入  中
                st.push(NULL); //并添加空节点作为标识
                if(node->left) st.push(node->left);  //左
            }
            else{   //如果node不是空节点,则可取为res
                st.pop();
                node=st.top();
                st.pop();
                res.push_back(node->val);
            }
        }
        return res;
    }
};

前序:相比中序,只改变了两行的顺序

class Solution {
public:
    vector<int> preorderTraversal(TreeNode* root) {
        stack<TreeNode*> st;
        vector<int> res;
        if(root!=NULL) st.push(root);
        while(!st.empty()){
            TreeNode* node=st.top();
            if(node!=NULL){
                st.pop();
                if(node->right) st.push(node->right); //右
                if(node->left) st.push(node->left);   //左
                st.push(node);   //中
                st.push(NULL);   //标识
            }
            else{
                st.pop();
                node=st.top();
                st.pop();
                res.push_back(node->val);
            }
        }
        return res;
    }
};

后序:

class Solution {
public:
    vector<int> postorderTraversal(TreeNode* root) {
        stack<TreeNode*> st;
        vector<int> res;
        if(root!=NULL) st.push(root);
        while(!st.empty()){
            TreeNode* node=st.top();
            if(node!=NULL){
              st.push(NULL);  //中
              if(node->right) st.push(node->right);  //右
              if(node->left) st.push(node->left);   //左
            }
            else{
                st.pop();
                node=st.top();
                st.pop();
                res.push_back(node->val);
            }
        }
        return res;
    }
};

层序遍历:

文章链接:https://programmercarl.com/0102.二叉树的层序遍历.html#_102-二叉树的层序遍历
题目链接:https://leetcode.cn/problems/binary-tree-level-order-traversal/

class Solution {
public:
    vector<vector<int>> levelOrder(TreeNode* root) {
        vector<vector<int>> res;
        queue<TreeNode*> que;
        int size=0;
        if(root!=NULL){
            que.push(root);
            size++;
        }
        while(!que.empty()){
            vector<int> curRes;
            int i=0;  //这里我取了i来整体记录size的最终变化。
                      //实际上可以用que的库函数size()来得到当前的元素个数
            while(size--){
                TreeNode* node=que.front();
                que.pop();
                if(node->left){
                    que.push(node->left);
                    i++;
                }
                if(node->right){
                    que.push(node->right);
                    i++;
                }
                curRes.push_back(node->val);
            }
            size=i;
            res.push_back(curRes);
        }
        return res;
    }
};
posted @ 2024-10-24 20:14  W-Vicky11  阅读(191)  评论(0编辑  收藏  举报