1. 二叉樹的寬度
若某一層的節點數不少於其他層次的節點數,那么該節點數即為二叉樹的寬度。在訪問過程中,我們只需要將同一層中的節點同時入棧即可。為此,我們也只需要知道上一層隊列中元素的多少,在將該queue中所有元素出隊列的同時,將下一層的元素進隊列,完成交接。這樣,便可以清晰地知道每一層中節點的多少,自然也知曉樹的寬度。
1 int treeWidth(Bitree *root){ 2 if(!root){ 3 return 0; 4 } 5 int width = 0; 6 int maxWidth = 0; 7 queue<Bitree *> Q; 8 Bitree *p = nullptr; 9 Q.push(root); 10 while(!Q.empty()){ 11 width = Q.size(); 12 if(maxWidth < width){ 13 maxWidth = width; 14 } 15 for(int i=0; i<width; i++){ 16 p = Q.front(); 17 Q.pop(); 18 if(p->left){ 19 Q.push(p->left); 20 } 21 if(p->right){ 22 Q.push(p->right); 23 } 24 } 25 } 26 return maxWidth; 27 }
2. 樹的高度
在上述算法中,知道了每一層中節點的個數,其實也很容易知道樹的高度,簡直就是順便的事。由此,可以給出相應的非遞歸算法。
1 int treeHeight2(Bitree *root){ 2 if(!root){ 3 return 0; 4 } 5 int height = 0; 6 int width = 0; 7 queue<Bitree *> Q; 8 Bitree *p = nullptr; 9 Q.push(root); 10 while(!Q.empty()){ 11 width = Q.size(); 12 height++; 13 for(int i=0; i<width; i++){ 14 p = Q.front(); 15 Q.pop(); 16 if(p->left){ 17 Q.push(p->left); 18 } 19 if(p->right){ 20 Q.push(p->right); 21 } 22 } 23 } 24 return height; 25 }
當然,對於樹的高度,還有一種代碼簡潔的遞歸算法,也一並呈上。
1 int treeHeight1(Bitree *root){ 2 if(!root){ 3 return 0; 4 } 5 int leftHeight = treeHeight1(root->left); 6 int rightHeight = treeHeight1(root->right); 7 return leftHeight>rightHeight ? leftHeight+1 :rightHeight+1; 8 }
遞歸思想其實很簡單,代碼也清晰易懂,即左右子樹的較高者加上1(root高度為1)即可。樹的高度等價於從根節點到葉子節點的最長路徑的長度,后續博主也會討論到其他變體,例如求解從根節點到葉子節點的最短路徑長度。