You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在不使用递归、栈或Morris遍历的前提下迭代中序遍历AVL树

无递归、无栈、无Morris修改的AVL树迭代中序遍历方案

AVL树本质是自平衡二叉搜索树,我们可以利用BST的后继节点特性,结合AVL的平衡属性(保证每次后继查找的时间是O(log n)),实现完全符合你要求的遍历——不用递归、栈,也不修改树结构。

核心思路很简单:从树的最左节点(中序遍历的第一个节点)开始,逐个找到当前节点的后继节点并访问,直到所有节点都被遍历完。

1. 定位遍历起点

中序遍历的第一个节点必然是树的最左节点,也就是从根节点一路往左走,直到没有左子节点为止:

def get_leftmost(node):
    while node.left:
        node = node.left
    return node

2. 查找后继节点

对于BST中的节点,后继是比它大的最小节点,分两种情况处理:

  • 如果当前节点有右子树,后继就是右子树的最左节点(和找起点的逻辑一样)。
  • 如果没有右子树,就得从根节点重新往下找:记录第一个比当前节点大的祖先节点,这个节点就是后继——因为BST中,所有比当前节点大的节点里,这个祖先就是最小的那个。

代码实现(假设节点包含key、left、right三个属性):

def get_successor(root, curr):
    successor = None
    temp = root
    while temp:
        if curr.key < temp.key:
            successor = temp
            temp = temp.left
        elif curr.key > temp.key:
            temp = temp.right
        else:
            break  # 找到当前节点,停止遍历
    # 优先处理有右子树的情况
    if curr.right:
        return get_leftmost(curr.right)
    return successor

3. 完整遍历流程

把上面两个部分拼起来,从最左节点开始,循环访问节点并找后继,直到后继为空:

def avl_inorder_traversal(root):
    if not root:
        return []
    result = []
    curr = get_leftmost(root)
    while curr:
        result.append(curr.key)
        curr = get_successor(root, curr)
    return result

补充说明

  • 时间复杂度:每个节点的后继查找是O(log n),n个节点总时间是O(n log n),虽然比栈实现的O(n)稍慢,但完全满足你的约束条件。
  • 空间复杂度:只用了几个临时变量,属于O(1)的额外空间,没有用栈、递归栈,也没修改树的任何结构。
  • 为什么AVL树适用?因为AVL是平衡的,每次从根找后继的时间稳定在O(log n),不会出现退化成链表的情况,保证了效率。

内容的提问来源于stack exchange,提问作者Iulian Bodea

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 19:30:52