给定一棵仅由加减法运算符、数字组成的二进制算术表达式树,如何使树尽可能平衡?任务是在不求表达式值的情况下平衡树,即节点数应该保持不变。
示例:
+ +
/ \ / \
+ 15 >>>>>> - +
/ \ / \ / \
5 - 6 4 5 15
/ \
6 4
加法是可交换的和相联的,这允许平衡。交换性允许交换连续“+”节点的子节点。关联性允许旋转。在上述示例中,所执行的转换可以被视为
另一种方法可以是将表达式树读入数组,并用变量替换任何'-'子树。然后使用DP确定括号的最佳位置。这必须是自下而上的,这样任何'-'子树在被DP算法考虑时就已经是平衡的了。但是,我很担心,因为可能有(N+1)!排列节点和括号的方法。而我正在寻找一个O(n)算法。
这是一个已知的问题吗?有没有具体的解决方法?
冒着做一些模糊的“评估”(尽管在我看来不是这样)的风险,我会做以下几点:
>
通过将否定标记向下传播到根,将整个树更改为添加节点。一个简单的方法是为每个叶子节点添加一个“颜色”。节点的颜色可以在树的行走过程中直接计算。在遍历过程中,您将跟踪来自-节点的右侧链接的数字(或奇偶校验,因为这是我们唯一感兴趣的部分);当到达一片叶子时,如果奇偶为偶数,则为绿色,如果奇数为奇数,则为红色。(红叶被否定。)在遍历过程中,-节点更改为+。
+ +
/ \ / \
+ 15 >>>>>> + 15
/ \ / \
5 - 5 +
/ \ / \
6 4 6 -4
现在通过在树叶顶部构造一个最小深度二叉树来最小化树的深度,将树叶按顺序排列,而不考虑前面的树结构:
+ +
/ \ / \
+ 15 >>>>>> + +
/ \ / \ / \
5 + 5 6 -4 15
/ \
6 -4
棘手的情况是节点的所有子节点都是红色的。在这种情况下,向上移动树,直到找到一个有绿色后代的父代。您找到的节点必须有两个子节点(否则它的唯一子节点必须有一个绿色的后代节点),其中只有一个子节点有绿色的后代节点。然后,将该节点更改为-,如果右侧子节点有绿色后代,则将其子节点反转,并将右侧子节点(可能是新的)的所有子节点重新着色为绿色。
+ +
/ \ / \
+ + >>>>>> + -
/ \ / \ / \ / \
5 6 -4 15 5 6 15 4
也许值得指出的是,根节点在左侧有一个绿色的后代,因为第一个叶节点是绿色的。这足以证明上述算法涵盖了所有情况。
我在骆驼路线中使用了这个表达: 然而,它对这个符号感到震惊。 如何构造这个表达式,假定它从消息体上POJO的getter获取一个值,并将其压缩到Exchange上的一个属性(加1)。
我们将简单浏览一下运算符和它们的用法: 技巧 你可以交互地使用解释器来计算例子中给出的表达式。例如,为了测试表达式2 + 3,使用交互式的带提示符的Python解释器: >>> 2 + 3 5 >>> 3 * 5 15 >>> 表5.1 运算符与它们的用法 运算符 名称 说明 例子 + 加 两个对象相加 3 + 5得到8。'a' + 'b'得到'ab'。 - 减 得到负数或是一个数减去另一个数 -
使用表达式 例5.1 使用表达式 #!/usr/bin/python # Filename: expression.py length =5 breadth =2 area = length * breadth print'Area is', area print'Perimeter is', 2* (length + breadth) (源文件:code/expression.py) 输出 $
你所编写的大多数语句(逻辑行)都包含了表达式(Expressions)。一个表达式的简单例子便是 2+3。表达式可以拆分成运算符(Operators)与操作数(Operands)。 运算符(Operators)是进行某些操作,并且可以用诸如 + 等符号或特殊关键词加以表达的功能。运算符需要一些数据来进行操作,这些数据就被称作操作数(Operands)。在上面的例子中 2 和 3 就是操作数。 运算
表达式是运算符和操作数(operand)的集合,或者是常量。 通常用以下格式书写。 表达式; 像这样在表达式的后面加上分号(;)的话,该表达式会被当场求值( = 执行 ),而产生的结果会被丢弃。 例: a=b; //由于=运算符的作用,b变量的值被代入到a变量中 func(); //由于()运算符的作用,func作为函数被调用,函数的返回值被舍弃 1+3; //由于+运算符的作用,1和3被求
常用运算符分类 运算符是用来操作数据的,因此,这些数据也被称为操作数,使用运算符将操作数连接而成的式子称为表达式。表达式具有如下特点: 常量和变量都是表达式 运算符的类型对应表达式的类型 每一个表达式都有自己的值,即表达式都有运算结果。 运算符类型 作用 算术运算符 用于处理四则运算 赋值运算符 用于将表达式的值赋给变量 比较运算符 用于表达式的比较,并返回一个真值或假值 逻辑运算符 用于根据表达