《编程之美》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<<" 该层有"<<nEnd<<"个元素!"; 29 } 30 } 31 cout<<endl; // 每一行输出换行 32 } 33 }
希望各位看官不吝赐教,小弟感谢