代码随想录算法训练营第十四天,第六章 二叉树 | 144.二叉树的前序遍历 145.二叉树的后序遍历 94.二叉树的中序遍历

使用递归进行前中后序遍历

为什么可以使用递归的方法进行前中后序遍历?(以前序遍历为例)

  1. 大问题拆成两个子问题
  2. 子问题的求解方式和大问题的求解方式是一样的
  3. 存在最小问题
    在这里插入图片描述

递归算法的编程技巧

  1. 确定递归函数的参数和返回值: 确定哪些参数是递归的过程中需要处理的,那么就在递归函数里加上这个参数, 并且还要明确每次递归的返回值是什么进而确定递归函数的返回类型。
  2. 确定终止条件: 写完了递归算法, 运行的时候,经常会遇到栈溢出的错误,就是没写终止条件或者终止条件写的不对,操作系统也是用一个栈的结构来保存每一层递归的信息,如果递归没有终止,操作系统的内存栈必然就会溢出。
  3. 确定单层递归的逻辑: 确定每一层递归需要处理的信息。在这里也就会重复调用自己来实现递归的过程。

前序遍历为例:

  1. 确定递归函数的参数和返回值:因为要打印出前序遍历节点的数值,所以参数里需要传入vector在放节点的数值,除了这一点就不需要在处理什么数据了也不需要有返回值,所以递归函数返回类型就是void,代码如下:
void traversal(TreeNode* cur, vector<int>& vec)
  1. 确定终止条件:在递归的过程中,如何算是递归结束了呢,当然是当前遍历的节点是空了,那么本层递归就要要结束了,所以如果当前遍历的这个节点是空,就直接return,代码如下:
if (cur == nullptr) return;
  1. 确定单层递归的逻辑:前序遍历是中左右的循序,所以在单层递归的逻辑,是要先取中节点的数值,代码如下:
vec.push_back(cur->val);    // 中
traversal(cur->left, vec);  // 左
traversal(cur->right, vec); // 右

前序遍历

C++实现
class Solution{
public:
//    1.确定递归函数的参数和返回值:
    void traversal(TreeNode* cur, vector<int>& vec) {
//    2.确定终止条件:
        if(cur == nullptr)
            return;
//    3.确定单层递归的逻辑
        vec.push_back(cur->val);   //中
        traversal(cur->left, vec);   //左
        traversal(cur->right, vec);  //右
    }
    vector<int> preorderTraversal(TreeNode* root) {
        vector<int> result;
        traversal(root, result);
        return result;
    }

};
python实现
class Solution:
    def preorderTraversal(self, root: TreeNode) -> List[int]:
        # 保存结果
        result = []
        
        def traversal(root: TreeNode):
            if root == None:
                return
            result.append(root.val) # 前序
            traversal(root.left)    # 左
            traversal(root.right)   # 右

        traversal(root)
        return result

中序遍历

C++实现
class Solution{
public:
//    1.确定递归函数的参数和返回值:
    void traversal(TreeNode* cur, vector<int>& vec) {
//    2.确定终止条件:
        if(cur == nullptr)
            return;
//    3.确定单层递归的逻辑
        
        traversal(cur->left, vec);   //左
        vec.push_back(cur->val);   //中
        traversal(cur->right, vec);  //右
    }
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int> result;
        traversal(root, result);
        return result;
    }

};
python实现
class Solution:
    def inorderTraversal(self, root: TreeNode) -> List[int]:
        result = []

        def traversal(root: TreeNode):
            if root == None:
                return
            traversal(root.left)    # 左
            result.append(root.val) # 中序
            traversal(root.right)   # 右

        traversal(root)
        return result

后序遍历

C++实现
class Solution{
public:
//    1.确定递归函数的参数和返回值:
    void traversal(TreeNode* cur, vector<int>& vec) {
//    2.确定终止条件:
        if(cur == nullptr)
            return;
//    3.确定单层递归的逻辑
        
        traversal(cur->left, vec);   //左
        traversal(cur->right, vec);  //右
        vec.push_back(cur->val);   //后
    }
    vector<int> postorderTraversal(TreeNode* root) {
        vector<int> result;
        traversal(root, result);
        return result;
    }

};
python实现
class Solution:
    def postorderTraversal(self, root: TreeNode) -> List[int]:
        result = []

        def traversal(root: TreeNode):
            if root == None:
                return
            traversal(root.left)    # 左
            traversal(root.right)   # 右
            result.append(root.val) # 后序

        traversal(root)
        return result

参考文献

[1] 前序遍历为什么可以使用递归求解
[2] 代码随想录

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值