首页 > 编程语言 >代码随想录算法训练营第24天(补第12天)| 递归遍历,迭代遍历,统一迭代

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

时间:2024-10-24 20:09:31浏览次数:8  
标签:node 遍历 cur 迭代 res 随想录 st push root

前置知识

二叉树的定义:

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;
    }
};

标签:node,遍历,cur,迭代,res,随想录,st,push,root
From: https://www.cnblogs.com/VickyWu/p/18500379

相关文章

  • 代码随想录算法训练营第九天|leetcode151.翻转字符串里的单词、卡码网55.右旋字符串
    1leetcode151.翻转字符串里的单词题目链接:151.反转字符串中的单词-力扣(LeetCode)文章链接:代码随想录视频链接:字符串复杂操作拿捏了!|LeetCode:151.翻转字符串里的单词_哔哩哔哩_bilibili自己的思路:直接将空格去掉,然后分割字符串为列表,在列表中进行翻转,不在字符串内部操作,......
  • 人工智能理论基础之Numpy(迭代数组、数组操作、数组元素的增删改查、统计函数)
    文章目录前言一、迭代数组1、order参数2.flags参数3.op_flags参数10.数组操作10.1数组变维![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/6bf02c9132084106997478c5fceaf495.png)10.1.1flat10.1.2flatten()10.1.3ravel()10.2数组转置10.3修改数组维度......
  • 代码随想录算法训练营第二十四天|Day24 回溯算法
    93.复原IP地址题目链接/文章讲解:https://programmercarl.com/0093.%E5%A4%8D%E5%8E%9FIP%E5%9C%B0%E5%9D%80.html视频讲解:https://www.bilibili.com/video/BV1XP4y1U73i/思路char**result;intresultTop;intsegments[3];intisValid(char*s,intstart,intend){......
  • 图的遍历(新)
    输入描述输入第一行为 n 和 m,表示有 n 个结点,编号从 1 到 n,m 表示有该图有 m 条边,接下来 m 行,每行两个整数 a 和 b,表示结点 a 到结点 b 有一条边。输出描述输出为两行,第一行为深度遍历的结果,第二行为广度遍历的结果,每个顶点间用一个‘-’符号隔开,假定每......
  • 代码随想录算法训练营 | 岛屿数量 深搜,岛屿数量 广搜,岛屿的最大面积
    岛屿数量深搜题目链接:岛屿数量深搜文档讲解︰代码随想录(programmercarl.com)日期:2024-10-23想法:Java代码如下:importjava.util.Scanner;publicclassMain{publicstaticint[][]dir={{0,1},{1,0},{-1,0},{0,-1}};publicstaticvoiddfs(boolean[][]v......
  • 【代码随想录Day50】图论Part02
    岛屿数量深搜题目链接/文章讲解:代码随想录classSolution{//计算网格中岛屿的数量publicintnumIslands(char[][]grid){intsum=0;//初始化岛屿数量为0//遍历整个网格for(inti=0;i<grid.length;i++){......
  • 代码随想录第七天
    454.四数相加II给你四个整数数组nums1、nums2、nums3和nums4,数组长度都是n,请你计算有多少个元组(i,j,k,l)能满足:0<=i,j,k,l<nnums1[i]+nums2[j]+nums3[k]+nums4[l]==0示例1:输入:nums1=[1,2],nums2=[-2,-1],nums3=[-1,2],nums4=[0,......
  • 迭代器
    迭代器概念:迭代器又称光标,是程序设计的软件设计模式。迭代器提供一个方法顺序访问一个聚合对象的各个元素,而不暴漏内部的标识。在表象上看,在外部用foreach遍历对象而不需要了解其结构的,都是实现迭代器的。标准迭代器的实现方法关键接口:IEnumerator,IEnumerable。命名空间:usin......
  • 代码随想录刷题学习日记
    仅为个人记录复盘学习历程,解题思路来自代码随想录代码随想录刷题笔记总结网址:代码随想录二叉树理论基础学习二叉树有两种主要的形式:满二叉树和完全二叉树。满二叉树:只有度为0的结点和度为2的结点,且度为0的结点在同一层的二叉树。深度为k,有2^k-1个节点。完全二叉树:除了最......
  • Python脚本,它将遍历指定目录下的所有.srt文件,移除其中的不必要的英文字符、不必要的空
    Python脚本,它将遍历指定目录下的所有.srt文件,移除其中的不必要的英文字符、不必要的空行以及不必要的空格。该脚本会保留字幕索引、字幕时间线以及字幕中的中文内容,并且只保留字幕中的中文内容。它还会保留字幕行与字幕之间的换行符,同时去掉字幕与字幕之间的不必要的换行符。处理......