算法训练-Day11 | 二叉树:递归遍历、迭代遍历、统一遍历、层序遍历

写递归算法的三要素:

1、确定递归函数的参数和返回值:确定哪些参数是递归的过程中需要处理的,就在递归函数里加上这个参数,并且根据返回值确定递归函数的返回类型。

2、确定终止条件:写完了递归算法, 运行的时候,经常会遇到栈溢出的错误,就是没写终止条件或者终止条件写的不对,操作系统也是用一个栈的结构来保存每一层递归的信息,如果递归没有终止,操作系统的内存栈必然就会溢出。

3、确定单层递归的逻辑:确定每一层递归需要处理的信息。通过重复调用单层递归来实现递归的过程

递归遍历

前序遍历如下,中序和后序遍历类似,只要改变取根节点值这一行代码的位置即可。

注意:这里所谓的前序、中序、后序指的是根节点的位置,如根节点在前,根左右,这就是前序遍历(也叫先序遍历)

/**
 * 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<vector<int>> levelOrder(TreeNode* root) {
        // 创建二叉树队列
        queue<TreeNode*> que;
        // 新建一个列表,返回结果
        vector<vector<int>> res;
        // 特例处理:当根节点为空时,返回空列表[]
        if(root != nullptr)
            que.push(root);

        // 队列不为空说明根节点不为空
        while(!que.empty()){
            // 新建一个临时列表,用于存储当前层队列打印结果
            vector<int> tmp;
            // 这里一定要使用固定大小的 size ,因为队列 que 的size是不断变化的,但是这里的size是要刚进入 while 循环时队列 que 的大小,而不是在经过 for 循环变化后的 size 大小
               
            int size = que.size();
            // 遍历当前层节点,存入临时列表中
            for(int i = 0;i < size ; i++){
                TreeNode* node = que.front();
                que.pop();
                tmp.push_back(node->val);
                if(node->left)    que.push(node->left);
                if(node->right)     que.push(node->right);
            }
            res.push_back(tmp);
        }
        return res;
    }
};

迭代遍历(后面有时间补充)

统一遍历(后面有时间补充)

层序遍历

解题思路

1、按层打印        2、每层打印到一行:将本层全部节点打印到一行,并将下一层全部节点加入队列,以此类推。

算法流程

1、特例处理:当根节点为空时,则返回空列表[ ]

2、初始化:打印结果的列表 res = [ ];包含根节点的队列 que = [root];

3、BFS循环:当队列  queue  为空时跳出。

        a、新建一个临时列表 tmp ,存储当前层的所有节点

        b、当前层打印:循环次数为当前层节点数(即队列 queue 长度)

                a、出队:队首元素出队,记为 node

                b、打印:将node->val 添加至 tmp 尾部

                c、添加子节点:若 node 的左右子节点不为空,则将左右子节点加入队列 queue 。

        c、将当前层结果 tmp 加入 res 中。

4、返回值:返回打印结果列表 res 。

/**
 * 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<vector<int>> levelOrder(TreeNode* root) {
        // 创建二叉树队列
        queue<TreeNode*> que;
        // 特例处理:当根节点为空时,返回空列表[]
        if(root != nullptr)
            que.push(root);
        // 新建一个列表,返回结果
        vector<vector<int>> res;
        // 队列不为空说明根节点不为空
        while(!que.empty()){
            // 新建一个临时列表,用于存储当前层队列打印结果
            vector<int> tmp;
            int size = que.size();
            // 遍历当前层节点,存入临时列表中
            for(int i = 0;i < size ; i++){
                TreeNode* node = que.front();
                que.pop();
                tmp.push_back(node->val);
                if(node->left)    que.push(node->left);
                if(node->right)     que.push(node->right);
            }
            res.push_back(tmp);
        }
        return res;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值