我認爲最優雅的解決方案就是這個。是的,當然我有偏見。我是人類:-)
def countLeft (node,ind):
if node == null: return 0
return ind + countLeft (node->left, 1) + countLeft (node->right, 0)
total = countLeft (root, 0)
通過向下傳遞左節點的指標,它簡化了必須傳遞的內容。下圖顯示了每個傳遞的總和 - 您從底部開始,每個null都遞增0.
左側的每個節點都會傳遞1以及來自兩個分支的任何節點。右側的每個節點都會傳遞0加上來自兩個分支的任何節點。
根本沒有增加任何東西,因爲它既不是左邊節點也不是右邊節點(它的處理方式與右邊相同)。
4
^
|
+---+
| 3 |
__________+---+__________
/2 2\
+---+ +---+
| 5 | | 2 |
+---+ +---+
/1 /2 0\
+---+ +---+ +---+
| 1 | | 4 | | 6 |
+---+ +---+ +---+
/0 0\ /1 0\ /0 0\
+---+
| 7 |
+---+
/0 0\
你可以從這個完整的程序見操作:
#include <stdio.h>
typedef struct sNode { int val; struct sNode *left, *right; } tNode;
#define setNode(N,V,L,R) N.val = V; N.left = L; N.right = R
int countLeft (tNode *node, int ind) {
if (node == NULL) return 0;
int x = ind + countLeft (node->left, 1) + countLeft (node->right, 0);
printf ("Node %d passing up %d\n", node->val, x);
return x;
}
int main (void) {
tNode n3, n5, n1, n2, n4, n6, n7;
setNode (n3, 3, &n5, &n2);
setNode (n5, 5, &n1, NULL);
setNode (n1, 1, NULL, NULL);
setNode (n2, 2, &n4, &n6);
setNode (n4, 4, &n7, NULL);
setNode (n7, 7, NULL, NULL);
setNode (n6, 6, NULL, NULL);
printf ("countLeft is %d\n", countLeft (&n3, 0));
return 0;
}
,它輸出的調試線路:
Node 1 passing up 1
Node 5 passing up 2
Node 7 passing up 1
Node 4 passing up 2
Node 6 passing up 0
Node 2 passing up 2
Node 3 passing up 4
countLeft is 4
的countLeft
函數的非調試版本就像這個答案開始時的僞代碼一樣簡單:
int countLeft (tNode *node, int ind) {
if (node == NULL) return 0;
return ind + countLeft (node->left, 1) + countLeft (node->right, 0);
}
它會不會命中空指針exxeption? – Catie 2010-11-02 09:05:59
@Catie:不,因爲它所做的第一件事是檢查null,然後在這種情況下返回0。這是執行此操作的標準方法,因此您不必將根節點視爲特殊節點。 – paxdiablo 2010-11-02 09:13:11