[程式設計之美][3.10] 分層遍歷二叉樹

菜鳥加貝的爬升發表於2013-10-07

 

  《程式設計之美》3.10節中主要針對二叉樹的分層遍歷進行了講述,其實在《劍指Offer》一書中”面試題23:從上到下列印二叉樹“ 實質上也是針對樹結構的按層遍歷演算法。解法使用一個佇列實現。採用遞迴,程式碼如下:

 1 struct TreeNode{
 2     TreeNode *left;
 3     TreeNode *right;
 4 
 5     int value;
 6 };
 7 
 8 void visitTreeByLevel(TreeNode *root){
 9     if(NULL == root){
10         return;
11     }
12 
13     queue<TreeNode *> visitQue;
14     visitQue.push(root);
15 
16     while(!visitQue.empty()){
17         TreeNode *curNode = visitQue.front();
18         if(curNode->left){
19             visitQue.push(curNode->left);
20         }
21         if(curNode->right){
22             visitQue.push(curNode->right);
23         }
24         printf("%d ", curNode->value);
25         visitQue.pop();
26     }
27 }

  而在《程式設計之美》一書中有更進一步的要求: 樹結構每一層需要單獨輸出一行,因此我們需要標記每一行的起始,以便進行行的結束和下一行資料的開始。因此我們定義兩個標示記錄每一行的開始和結束,而每次每一行遍歷結束的時候實際上已經取得了此行的元素個數。那麼這樣自然而然我們使用該行元素個數為結束標記,並且需要在遍歷完畢每一行資料之後重新設定標示。 程式碼如下:

 1 void visitTreeByLevel(TreeNode*  pRoot){
 2     if (NULL == pRoot){
 3         return;
 4     }
 5 
 6     queue<TreeNode*> visitQue;
 7     visitQue.push(pRoot);
 8 
 9     while (visitQue.size()>0){
10         int nBegin = 0;
11         int nEnd = visitQue.size();
12         
13         while (nBegin < nEnd){        // 每次將該層全部便利完畢之後 再設定新的標識
14             TreeNode* pElem = visitQue.front();
15             if (pElem->left){
16                 visitQue.push(pElem->left);
17             }
18 
19             if (pElem->right){
20                 visitQue.push(pElem->right);
21             }
22 
23             cout<<pElem->value<<" ";
24             nBegin++;                // 追趕end
25             visitQue.pop();
26 
27             if (nBegin == nEnd){
28                 cout<<"\t\t\t該層有"<<nEnd<<"個元素!";
29             }
30         }
31         cout<<endl;                    // 每一行輸出換行
32     }
33 }

 

希望各位看官不吝賜教,小弟感謝

 

 

相關文章