《程式設計之美》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 }
希望各位看官不吝賜教,小弟感謝