[英]Loop invariant for the sum of a binary tree
我想為下面的一段代碼找到一個循環不變量,我似乎無法弄清楚這段代碼中呈現的任何類型的關系。
該算法的目標是找到二叉樹中所有元素的總和。 它將節點存儲在一個名為s
的堆棧中。
def TreeSum(root):
res = 0
s.push(root)
while s.size > 0:
node = s.pop()
res = res + node.num
if node.right != None:
s.push(node.right)
elif node.left != None:
s.push(node.left)
return res
我注意到res
是所有當前節點的父節點以及其父節點左側的總和,但我不知道如何將其表述為循環不變量。
該算法應該計算二叉樹中數字的總和。 為了證明它的正確性,有兩個重要的事實需要證明:首先它確實計算了它訪問的節點的總和,其次它訪問了每個節點一次。 因此,我們需要找到至少兩個不變量,一個用於證明這些事實中的每一個。
為了更正式地討論“已訪問”或“未訪問”節點,讓我們在算法中添加幾行代碼,以跟蹤“已訪問”節點列表。 這些行顯然不會改變算法的行為,因為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
的總和 for a in visited
invisited 。a in visited
, and all nodes c not in visited
which are descendants of a
, either c in s
or there is a unique node b in s
such that b
is a descendant of a
and an ancestor of c
.root in s
或root in visited
。 需要第三個不變量來得出結論,當循環終止時, visited
包含每個節點,因此res
是每個節點的總和。 如果沒有這個,其他兩個不變量在visited
為空且res
為0 時得到滿足,但第三個不變量允許我們拒絕這種可能性。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.