二叉树的中序遍历模板 包括递归,迭代,莫里斯遍历

# 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: Optional[TreeNode]
        :rtype: List[int]
        """
        # res = []
        # cur = root
        # stack = []
        # while cur or stack:
        #     while cur:
        #         stack.append(cur)
        #         cur = cur.left
        #     cur = stack.pop()
        #     res.append(cur.val)
        #     cur = cur.right
        # return res

        # 最容易版本
        # if not root:
        #     return []

        # return self.inorderTraversal(root.left) + [root.val] + self.inorderTraversal(root.right)
        

        # 递归通用模板,适应不同题型,添加参数,返回条件,修改进入递归条件,自定义返回值
        # def dfs(cur):
        #     if not cur:
        #         return 
            
        #     dfs(cur.left)
        #     res.append(cur.val)
        #     dfs(cur.right)
        # res=[]
        # dfs(root)
        # return res

        # 迭代的层序遍历
        # if not root:
        #     return []
        # cur ,res = [root] , []
        # while cur:
        #     lay ,layval = [],[]
        #     for node in cur:
        #         layval.append(node.val)
        #         if node.left: lay.append(node.left)
        #         if node.right: lay.append(node.right)
        #     cur = lay
        #     res.append(layval)
        # return res

        # 迭代的前中后序遍历  中序遍历
        # cur = root
        # stack = []
        # res = []
        # while cur or stack:
        #     while cur:
        #         stack.append(cur)
        #         cur = cur.left
        #     cur = stack.pop()
        #     res.append(cur.val)
        #     cur = cur.right


        # 使用栈的前序遍历
        # cur = root
        # res ,stack = [], [] 
        # while cur or stack:

        #     while cur:
        #         stack.append(cur)
        #         res.append(cur.val)
        #         cur= cur.left
        #     cur = stack.pop()
        #     cur = cur.right
        # return res

        # # 后续遍历 先按照右左中的顺序,然后反过来
        # cur = root
        # res ,stack = [], [] 
        # while cur or stack:

        #     while cur:
        #         stack.append(cur)
        #         res.append(cur.val)
        #         cur= cur.right
        #     cur = stack.pop()
        #     cur = cur.left
        # return res[::-1]
        # return res



        # 标记迭代法 中序遍历 
        # stack = []
        # res = []
        # stack.append((0,root))
        # while stack:
        #     flag , cur = stack.pop()
        #     if not cur: continue
        #     if flag == 0:
        #         stack.append((0,cur.right))
        #         stack.append((1,cur))
        #         stack.append((0,cur.left))
        #     else:
        #         res.appned(cur.val)
        # return res

        # 莫里斯遍历
        # 
        # res = []

        # while root:
        #     if root.left:
        #         pre = root.left
        #         while pre.right:
        #             pre = pre.right
        #         pre.right = root
        #         tmp = root
        #         root = root.left
        #         tmp.left = None
        #     else:
        #         res.append(root.val)
        #         root = root.right

        # return res

        res = []
        while root:
            if root.left:
                pre = root.left
                while pre.right:
                    pre = pre.right
                pre.right = root
                # 在前序遍历中,首次访问节点时就添加其值
                res.append(root.val)
                tmp = root
                root = root.left
                tmp.left = None
            else:
                # 左指针为空时,除了移动到右子树,也要添加节点值
                res.append(root.val)
                root = root.right

        return res

    












记住遍历模板,走遍天下都不怕

### Java中实现二叉树序遍历的方法 #### 方法概述 在Java中,可以通过多种方法实现二叉树的中序遍历。常见的方法包括递归迭代以及莫里斯遍历(Morris Traversal)。以下是每种方法的具体实现。 --- #### 1. **递归实现** 递归是最直观的方式之一,其核心思想是按照“左子树 -> 根节点 -> 右子树”的顺序访问节点[^2]。 ```java public List<Integer> inorderTraversal(TreeNode root) { List<Integer> result = new ArrayList<>(); helper(root, result); return result; } private void helper(TreeNode node, List<Integer> resultList) { if (node != null) { helper(node.left, resultList); // 访问左子树 resultList.add(node.val); // 处理当前节点 helper(node.right, resultList); // 访问右子树 } } ``` 这种方法的时间复杂度为O(n),空间复杂度取决于递归调用栈的深度,最坏情况下为O(h),其中h为树的高度[^4]。 --- #### 2. **迭代实现** 为了减少递归带来的额外开销,可以使用显式的栈来模拟递归过程。这种方式同样遵循“左子树 -> 根节点 -> 右子树”的原则[^1]。 ```java import java.util.*; public List<Integer> inorderTraversalIterative(TreeNode root) { List<Integer> result = new ArrayList<>(); Stack<TreeNode> stack = new Stack<>(); TreeNode current = root; while (current != null || !stack.isEmpty()) { while (current != null) { // 将左子树压入栈中 stack.push(current); current = current.left; } current = stack.pop(); // 弹出并处理当前节点 result.add(current.val); current = current.right; // 转向右子树 } return result; } ``` 该方法的空间复杂度由使用的栈决定,时间复杂度仍为O(n)[^1]。 --- #### 3. **莫里斯遍历(Morris Traversal)** 莫里斯遍历是一种不需要额外存储空间的高效算法,通过修改树中的指针完成遍历。它利用叶子节点的空闲指针指向其他节点,从而避免了使用栈或递归[^2]。 ```java public List<Integer> morrisInorderTraversal(TreeNode root) { List<Integer> result = new ArrayList<>(); TreeNode current = root; while (current != null) { if (current.left == null) { // 如果没有左子树,则直接访问当前节点 result.add(current.val); current = current.right; } else { TreeNode predecessor = findPredecessor(current); // 找到前驱节点 if (predecessor.right == null) { // 建立临时链接 predecessor.right = current; current = current.left; } else { // 断开临时链接并访问当前节点 predecessor.right = null; result.add(current.val); current = current.right; } } } return result; } // 寻找当前节点的前驱节点 private TreeNode findPredecessor(TreeNode node) { TreeNode pre = node.left; while (pre.right != null && pre.right != node) { pre = pre.right; } return pre; } ``` 这种算法的空间复杂度为O(1),因为不依赖于任何额外的数据结构。 --- ### 性能对比 | 方法 | 时间复杂度 | 空间复杂度 | |---------------|------------|-------------| | 递归 | O(n) | O(h) | | 迭代(栈) | O(n) | O(h) | | 莫里斯遍历 | O(n) | O(1) | 以上表格展示了不同方法的性能特点,开发者可以根据实际需求选择合适的方案[^1]。 --- ### 结论 对于初学者来说,递归和基于栈的迭代方法更为直观易懂;而对于追求极致性能的应用场景,莫里斯遍历则是一个不错的选择。无论采用哪种方法,都应确保代码逻辑清晰且易于维护。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值