返回

恢复二叉搜索树的多种优雅解法:重拾数据结构的平衡

前端

二叉搜索树的平衡之道

二叉搜索树,作为计算机科学中的重要数据结构,以其有序性和高效检索特性而闻名。然而,当节点错误交换时,这棵平衡树会失去其应有的优雅。恢复二叉搜索树的挑战,是对数据结构操作技能的一次考验。

多种解法,殊途同归

递归:简洁直观

递归算法以其简洁性和可读性而著称。通过递归遍历整棵树,我们可以找到被交换的节点对,然后进行交换,恢复树的平衡。

迭代:步步为营

迭代算法使用栈或队列等数据结构,逐层遍历树,避免了递归可能带来的栈溢出问题。通过巧妙地利用数据结构,迭代算法同样可以高效地恢复二叉搜索树。

Morris 遍历:巧妙高效

Morris 遍历是二叉搜索树遍历的一种高级技巧,它巧妙地利用线索指针,在不使用额外空间的情况下进行遍历。通过 Morris 遍历,我们可以找到被交换的节点,并进行修复。

算法实战,代码呈现

递归解法:

def recoverTree(root):
    def dfs(node, prev):
        if not node:
            return
        dfs(node.left, prev)
        if prev and prev.val > node.val:
            self.swap(prev, node)
        prev = node
        dfs(node.right, prev)
    self.swap = lambda a, b: (a.val, b.val) = (b.val, a.val)
    dfs(root, None)

迭代解法:

def recoverTree(root):
    stack = []
    prev = None
    while stack or root:
        while root:
            stack.append(root)
            root = root.left
        root = stack.pop()
        if prev and prev.val > root.val:
            self.swap(prev, root)
        prev = root
        root = root.right
    self.swap = lambda a, b: (a.val, b.val) = (b.val, a.val)

Morris 遍历解法:

def recoverTree(root):
    prev = None
    while root:
        if not root.left:
            if prev and prev.val > root.val:
                self.swap(prev, root)
            prev = root
            root = root.right
        else:
            predecessor = root.left
            while predecessor.right and predecessor.right != root:
                predecessor = predecessor.right
            if not predecessor.right:
                predecessor.right = root
                root = root.left
            else:
                if prev and prev.val > root.val:
                    self.swap(prev, root)
                prev = root
                predecessor.right = None
                root = root.right
    self.swap = lambda a, b: (a.val, b.val) = (b.val, a.val)

结语

恢复二叉搜索树是一道经典算法问题,考验着算法工程师的数据结构操作能力和解决问题思路。通过递归、迭代和 Morris 遍历等不同解法的学习,我们加深了对二叉搜索树性质和操作的理解。选择合适的解法,既能展现算法之美,又能提升代码效率,在数据结构的平衡之道上更进一步。