该算法应用于计算二叉树中数字的总和。为了证明其正确性,有两个重要事实需要证明:首先,它确实计算了它访问的节点的总和;其次,它访问了每个节点一次。因此,我们将需要至少找到两个不变量,一个用于证明每个事实。
为了更正式地讨论“已访问”或“未访问”节点,让我们在算法中添加几行内容,以跟踪“已访问”节点的列表。这些行显然不会改变算法的行为,因为visited
仅被写入,从不读取:
def TreeSum(root):
res = 0
s = Stack()
s.push(root)
visited = [] # added line to simplify proof
while s.size > 0:
node = s.pop()
visited.append(node) # added line to simplify proof
res = res + node.num
if node.right != None:
s.push(node.right)
elif node.left != None:
s.push(node.left)
return res
我还添加了该算法必需的 行,以使s
为新堆栈,否则未定义s
或一个全局变量,那么我们不能保证算法启动时为空。
所需的不变式如下:
-
res
等于a.num
中a in visited
的总和。
- 对于
a in visited
的所有子节点c not in visited
和所有节点a
,c in s
或唯一的节点b in s
使得{ {1}}是b
的后代和a
的祖先。
-
c
或root in s
。
需要第三个不变量得出结论,root in visited
包含循环终止时的每个节点,因此visited
是每个节点的总和。没有这个,当res
为空且visited
为0时,其他两个不变量将得到满足,但是第三个不变量使我们可以拒绝这种可能性。
本文链接:https://www.f2er.com/3170024.html