首先,你自己試過了嗎?
基本上,它爲每個非零節點加1。大概是這樣的:1 + number_of_nodes_to_the_left + number_of_nodes_to_the_right
。這擴展到:1+(1+number_of_nodes_to_the_left_in_left+number_of_nodes_to_the_right_in_left) + (1+number_of_nodes_to_the_left_in_right + number_of_nodes_to_the_right_in_right)
。繼續擴展,您會看到樹中每個非空節點基本上都是1 + 1 + 1 +....
。
編輯:爲了說明這一點,不妨考慮下面的樹:
Node0
|
(left) | (right)
Node1 _|_ Node2
|
(left) | (right)
Node3 _|_ Node4
當你這樣做int node_count = count(Node0)
,因爲節點0不爲空,它關係到return語句是: return 1 + count(left) + count(right)
。您需要了解一個基本的事情,即您的遞歸函數中的某個操作只發生在其他操作之後。換句話說,直到操作count(left)
完成後纔會發生操作count(right)
。現在看看你在那裏的return語句,並根據上面的樹翻譯它。這將是1+count(Node1)+count(Node2)
。所以count(Node2)
在count(Node1)
完成之前沒有得到計算。因此,對於count(Node1)
,count函數將以Node1作爲參數被調用(再次)。因此,現在讓我們忘掉半計算表達式1+count(Node1)+count(Node2)
(我們稍後再回來)。
現在對於count(Node1)
,Node1不是NULL,因此進入return語句。這將(再次)是1+count(left)+count(right)
。但是等一下,Node1沒有左右節點。因此,當count(left)
被調用的參數爲NULL時,它將返回0,並且count(right)
也會發生同樣的情況。所以count(Node1)
的表達式變成1 + 0 + 0
。沒有更多的計數函數被調用Node1,因此它返回到它的原始調用者,這是返回語句count(Node0)
。
由於我們有count(Node1)
想通了,我們用count(Node0)
的返回語句替換它。現在變成1 + (1 + 0 + 0) + count(Node2)
。
現在我打算讓這個更快一點。由於Node2有兩個子節點,Node2的return語句將爲1 + count(Node3) + count(Node4)
。就像Node1,count(Node3)
和count(Node4)
將分別返回1 + 0 + 0
,將count(Node2)
的返回語句變爲1 + (1 + 0 + 0) + (1 + 0 + 0)
。
現在count(Node2)
已完全計算,讓我們迴歸到count(Node2)
原始調用者,這是1 + (1 + 0 + 0) + count(Node2)
。替換我們從count(Node2)
那裏得到的,我們得到1 + (1+0+0) + (1 + (1+0+0) + (1+0+0))
。把它加起來,我們得到5
的值。 將此值返回到稱爲count(Node0)
的任何函數,如語句int node_count = count(Node0)
和node_count
將具有值5
。
左節點是一個子樹。右節點也是一個子樹。函數調用自己,子樹作爲參數,計數遞增。現在,當計數器到達葉子時,它沒有任何孩子,所以它返回0.意義'葉子樹計數'。現在它達到了一級,結果是'1 +左葉數+右葉數'= 3'。同樣的,它還有一個更高的層次並且可以得到總數。 **假設所有節點都有離開葉子的左右兒童。那麼,概念不會改變** – Mayank 2011-05-05 10:17:38