二叉搜索树问题:将 BST 转换为左右节点数相差 1 的 BST

问题描述

我正在做一个问题,要求我平衡任何二叉搜索树,条件是每个级别的左右子树应该具有相同数量的节点或最多 1 个节点差异

我该如何解决这个问题? 到目前为止,我已经将树转换成一个链表......就是这样。我很确定那是第一步,但不太确定。我到处寻找资源,但我能找到的最接近的是 day-stout-warren 算法,该算法基于高度而不是节点数量进行平衡。

我只是在寻找伪代码

解决方法

这是一个在 O(n) 时间内工作的 Python 解决方案,就地使用 O(h) 辅助空间,其中 h 是树的高度;唯一的辅助数据结构是递归函数所需的堆栈。

它使用生成器函数工作,该函数在消费者改变树时迭代树,但我们在产生之前制作了 leftright 子树的本地副本它们,因此消费者可以在不破坏生成器的情况下重新分配它们。 (实际上只需要 right 的本地副本,但无论如何我都制作了本地副本。)

class Node:
    def __init__(self,data,left=None,right=None):
        self.data = data
        self.left = left
        self.right = right
    def __repr__(self):
        # display for debug/testing purposes
        def _r(n):
            return '*' if n is None else '(%s ← %r → %s)' % (_r(n.left),n.data,_r(n.right))
        return _r(self)

def balance(root):
    def _tree_iter(node):
        if node is not None:
            # save to local variables,could be reassigned while yielding
            left,right = node.left,node.right
            yield from _tree_iter(left)
            yield node
            yield from _tree_iter(right)
    
    def _helper(it,k):
        if k == 0:
            return None
        else:
            half_k = (k - 1) // 2
            left = _helper(it,half_k)
            node = next(it)
            right = _helper(it,k - half_k - 1)
            node.left = left
            node.right = right
            return node
    
    n = sum(1 for _ in _tree_iter(root))
    return _helper(_tree_iter(root),n)

示例:

>>> root = Node(4,left=Node(3,left=Node(1,right=Node(2))),right=Node(6,left=Node(5),right=Node(8,left=Node(7),right=Node(9))))
>>> root
(((* ← 1 → (* ← 2 → *)) ← 3 → *) ← 4 → ((* ← 5 → *) ← 6 → ((* ← 7 → *) ← 8 → (* ← 9 → *))))
>>> balance(root)
(((* ← 1 → *) ← 2 → (* ← 3 → (* ← 4 → *))) ← 5 → ((* ← 6 → *) ← 7 → (* ← 8 → (* ← 9 → *))))
,

将所有节点以中序遍历的方式加入到一个数组中,那么大致应该是这样的:


fun buildBalanced(
    array: Array,start: Int = 0,end: Int = array.length) -> Node {
  if (start >= end) {
    return nil
  }
  let middle = (start + end) / 2
  return new Node(
      array[middle],buildBalanced(array,start,middle),middle + 1,end))  
}

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...