二叉树-前中后递归/迭代遍历

二叉树的理论基础

参考https://programmercarl.com/%E4%BA%8C%E5%8F%89%E6%A0%91%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html

二叉树的定义

struct TreeNode {
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
 
class TreeNode: 
    def __init__(self, value):
        self.value = value
        self.left = None
        self.right = None

二叉树的递归遍历

递归要素:

  • 确定递归函数的参数和返回值

  • 确定终止条件

  • 确定单层递归的逻辑

144. 二叉树的前序遍历

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def preorderTraversal(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        result = []

        def travelsal(root):
            # 当前遍历的结点为空 结束本层递归
            if root == None:
                return
            # 前序 中左右
            result.append(root.val)
            travelsal(root.left)
            travelsal(root.right)
        
        travelsal(root)
        return result
            

145.二叉树的后序遍历

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def postorderTraversal(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        result = []
        def traversal(root):
            if root == None:
                return
            # 后序 左右中
            traversal(root.left)
            traversal(root.right)
            result.append(root.val)
        
        traversal(root)
        return result

94.二叉树的中序遍历

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def inorderTraversal(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        result = []
        def traversal(root):
            if root == None:
                return
            # 中序 左中右
            traversal(root.left)
            result.append(root.val)
            traversal(root.right)
            
        
        traversal(root)
        return result

二叉树的迭代法

迭代操作:
处理:将元素放进result数组中
访问:遍历节点

前序遍历

 # Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def preorderTraversal(self, root: Optional[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



# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        if not root:
            return []
        res  = []
        stack = []
        cur = root
        while cur or stack :
            # 先遍历左子树
            if cur:
                stack.append(cur)
                res.append(cur.val)
                cur = cur.left
            #cur为空 赋新值
            else:
                cur = stack.pop()
                cur = cur.right
        return res

后序遍历

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        # 后序是【左右中】, 前序【中左右】
        # 先调整左右代码变【中右左】,再反转result数组变左【左右中】
        if not root:
            return []
        stack = [root]
        result = []
        while stack:
            node = stack.pop()
            result.append(node.val)
            # 先让左孩子入栈 这样出栈才会是【右左】 
            if node.left:
                stack.append(node.left)
            if node.right:
                stack.append(node.right)

        return result[::-1]
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
   
    def postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        if not root:
            return []
        res  = []
        stack = []
        cur = root
        while cur or stack :
            # 后序是左右中,所以先中右左(可以参考前序),再倒过来
            # 先遍历右子树
            if cur:
                stack.append(cur)
                res.append(cur.val)
                cur = cur.right
            #cur为空 赋新值
            else:
                cur = stack.pop()
                cur = cur.left
        return res[::-1]
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        if  not root:
            return []
        stack = []
        res = []
        cur  = root
        visited = None
        while stack or cur:
            print("cur",cur)
            # 后序 左右中,先遍历到最后一个左结点
            if cur:
                stack.append(cur)
                cur = cur.left
            # cur为空,赋值新结点
            else:
                # 取栈顶元素 如果有右孩子且当前右孩子没有被访问过 就先遍历到右孩子 如果无 就pop自己且打印自己,且标记为访问过
                cur = stack[-1]
                #设置visited 是因为当前结点不止一次经过,如果当前结点有右孩子,且没被访问过,不然会死循环,一直加入同一个节点的右孩子
                if cur.right and cur.right != visited:
                    cur = cur.right
                #右孩子为空
                else:
                    stack.pop()
                    res.append(cur.val)
                    visited = cur
                    cur = None #重置cur 因为pop了 需要重置cur

        return res

中序遍历

因为中序遍历是左中右,先访问的是二叉树顶部的节点,然后一层一层向下访问,直到到达树左面的最底部,再开始处理节点(也就是在把节点的数值放进result数组中),这就造成了处理顺序和访问顺序是不一致的。

那么在使用迭代法写中序遍历,就需要借用指针的遍历来帮助访问节点则用来处理节点上的元素。
在这里插入图片描述

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        if not root:
            return []
        stack = [] # 不能提前将root加入stack
        result = []
        cur = root 
        while cur or stack:
            # 先访问左子树
            if cur:
                stack.append(cur)
                cur= cur.left
            # 到达最左后处理栈顶结点
            else:
                cur = stack.pop()
                result.append(cur.val)
                # 取栈顶元素的右孩子
                cur = cur.right
        return result
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值