给定一个仅由加减法运算符和数字组成的二元算术表达式树,如何尽可能平衡树?任务是在不评估表达式的情况下平衡树,即节点的数量应该保持不变。
例子:
+ +
/ \ / \
+ 15 >>>>>> - +
/ \ / \ / \
5 - 6 4 5 15
/ \
6 4
加法是可交换的和关联的,并且允许平衡。交换性允许交换连续“+”节点的子节点。关联性允许旋转。在上面的例子中,执行的转换可以被视为
- 在根部的“+”上向右旋转。
- 交换“5”和“-”节点。
我正在考虑按顺序遍历并首先平衡任何子树。我会尝试通过尝试所有可能的节点排列(其中只有 12 个)来平衡具有两个连续“+”节点的任何子树,以希望降低树的总高度。此方法应在任何步骤将树的高度最多减少 1。但是,我无法确定它是否总是会给出最小高度的树,尤其是当有超过 2 个连续的“+”节点时。
另一种方法可能是将表达式树读入数组并用变量替换任何“-”子树。然后我们 DP 确定括号的最佳位置。这必须自下而上进行,以便任何“-”子树在 DP 算法考虑时已经平衡。但是,我很担心,因为可能有 (n+1)!排列节点和括号的方法。虽然我正在寻找 O(n) 算法。
这是一个已知问题吗?是否有具体的解决方法?