代码营打卡 Day14

1. 递归遍历(144)

  1. 确定递归函数的参数和返回值: 确定哪些参数是递归的过程中需要处理的,那么就在递归函数里加上这个参数, 并且还要明确每次递归的返回值是什么进而确定递归函数的返回类型。

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

  3. 确定单层递归的逻辑: 确定每一层递归需要处理的信息。在这里也就会重复调用自己来实现递归的过程.

前序是中左右的顺序, 用python写如下:

class Solution(object):


    def preorderTraversal(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        res= []
        def dfs(node):
            if node is None:
                return

            res.append(node.val)
            dfs(node.left)
            dfs(node.right)
        dfs(root)
        return res
    

后序遍历是左右中, 用python写如下:

class Solution(object):
    def postorderTraversal(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        res = []

        def dfs(node):
            if node is None:
                return
            
            dfs(node.left)        # 先处理左子树
            dfs(node.right)       # 再处理右子树
            res.append(node.val)  # 最后处理根节点
        
        dfs(root)
        return res
        

中序遍历是左中右, 如下:

class Solution(object):
    def inorderTraversal(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        res = []

        def dfs(node):
            if node is None:
                return
            
            dfs(node.left)        
            res.append(node.val)
            dfs(node.right)   
        
        dfs(root)
        return res

2. 二叉树的迭代遍历

2.1 前序和后序  

用递归的原理也是用栈来实现的, 所以迭代法也是用栈

首先前序就是中左右, 准备一个stack的栈来存储遍历的元素, 再准备一个vec数组来按顺序存储弹出的元素, 只要stack不为空, 就一直取stack中的栈尾元素(最后放入的), 再将此元素的中左右按照顺序放入栈中

class Solution {
public:
    vector<int> preorderTraversal(TreeNode* root) {
        stack<TreeNode*> st;
        vector<int> result;
        if (root == NULL) return result;
        st.push(root);
        while (!st.empty()) {
            TreeNode* node = st.top();                       // 中
            st.pop();
            result.push_back(node->val);
            if (node->right) st.push(node->right);           // 右(空节点不入栈)
            if (node->left) st.push(node->left);             // 左(空节点不入栈)
        }
        return result;
    }
};

python代码如下

class Solution:
    def preorderTraversal(self, root: TreeNode) -> List[int]:
        # 根结点为空则返回空列表
        if not root:
            return []
        stack = [root]
        result = []
        while stack:
            node = stack.pop()
            # 中结点先处理
            result.append(node.val)
            # 右孩子先入栈
            if node.right:
                stack.append(node.right)
            # 左孩子后入栈
            if node.left:
                stack.append(node.left)
        return result

 后序遍历是左右中, 只需要调换前序中的左右关系, 变成中右左, 然后输出的时候再逆向输出, 变成左右中即可

2.2 中序

中序遍历有点复杂, 顺序是左中右, 因为前面的遍历节点和处理节点的顺序一样, 但是中序遍历却不一样, 先访问的根节点5并不是要先处理的元素, 先处理的是根节点最左边的子节点1

所以stack应该先存储完5一路的左子节点, 541(即遇到叶子左节点为空时),然后再开始弹出. 例如1的左节点为空, 则弹出1, 1的右节点也为空, 则弹出4, 4的右节点为2则弹出2, 处理完5的左边节点4以后, 弹出5, 接着开始处理5的右边节点, 6左孩子为空, 弹出6以后, 右孩子为空, 栈也为空, 则结束

class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int> result;
        stack<TreeNode*> st;
        TreeNode* cur = root;
        while (cur != NULL || !st.empty()) {
            if (cur != NULL) { // 指针来访问节点,访问到最底层
                st.push(cur); // 将访问的节点放进栈
                cur = cur->left;                // 左
            } else {
                cur = st.top(); // 从栈里弹出的数据,就是要处理的数据(放进result数组里的数据)
                st.pop();
                result.push_back(cur->val);     // 中
                cur = cur->right;               // 右
            }
        }
        return result;
    }
};

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值