问题描述:输入一颗二元树,从上往下按层打印树的每个结点,同一层中按照从左往右的顺序打印。
例如输入
8
/ /
6 10
/ / / /
5 7 9 11
输出8 6 10 5 7 9 11。
定义二元树(其实是二元搜索树,但并不遍历算法)的结点为:
思路:利用队列的先进先出,很容易实现。每次取出队列的首元素,然后将其左右子女放入队列中。直至队列为空即可。按这种方式进出队列,正好是按层遍历二元树。
参考代码:
//函数功能 : 按层次遍历二元树 //函数参数 : pRoot指向根结点 //返回值 : 无 void LevelReverse(BSTreeNode *pRoot) { if(pRoot == NULL) return; queue<BSTreeNode *> nodeQueue; nodeQueue.push(pRoot); while(nodeQueue.size()) { BSTreeNode * pNode = nodeQueue.front(); //取队首元素 nodeQueue.pop(); //必须出队列 if(pNode->left) //左子女 nodeQueue.push(pNode->left); if(pNode->right) //右子女 nodeQueue.push(pNode->right); cout<<pNode->value<<' '; } }
扩展一:上文给出的代码,所有结点都输出在同一行。如果希望仅仅同层结点输出在同一行,该如何修改代码呢?
思路:如果我们能知道每层的最后一个结点,那么就方便多了,输出每层最后一个结点的同时,输出一个换行符。因此,关键在于如何标记每层的结束。可以考虑在每层的最后一个点之后,插入一个空结点。比如队列中先放入根结点,由于第0层只有一个结点,因此放入一个空结点。然后依次取出队列中的结点,将其子女放入队列中,如果遇到空结点,表明当前层的结点已遍历完了,而队列中放的恰恰是下一层的所有结点。如果当前队列为空,表明下一层无结点,也就说是所有结点已遍历好了。如果不为空,那么插入一个空结点,用于标记下一层的结束。
参考代码:
void LevelReverse(BSTreeNode *pRoot) { if(pRoot == NULL) return; queue<BSTreeNode *> nodeQueue; nodeQueue.push(pRoot); nodeQueue.push(NULL); //放入空结点,作为层的结束符 while(nodeQueue.size()) { BSTreeNode * pNode = nodeQueue.front(); //取队首元素 nodeQueue.pop(); //必须出队列 if(pNode) { if(pNode->left) //左子女 nodeQueue.push(pNode->left); if(pNode->right) //右子女 nodeQueue.push(pNode->right); cout<<pNode->value<<' '; } else if(nodeQueue.size()) //如果结点为空并且队列也为空,那么所有结点都已访问 { nodeQueue.push(NULL); cout<<endl; } } }
扩展二:之前讨论的都是从上往下、从左往右遍历二叉树,那么如果希望自下往上、从左右往右遍历二叉树,该如何修改代码呢?
思路:比较简单的方法,首先遍历二叉树,将所有结点保存在一个数组中,遍历的同时记录每一层在数组中的起止位置。然后根据起止位置,就可以自下往上的打印二叉树的结点。
//每层的起止位置 struct Pos { int begin; int end; Pos(int b, int e): begin(b),end(e) {} }; void LevelReverse(BSTreeNode *pRoot) { if(pRoot == NULL) return; vector<BSTreeNode*> vec; //用以存放所有结点 vector<Pos> pos; //用以记录每层的起止位置 vec.push_back(pRoot); int level = 0; //树的层数 int cur = 0; int last = 1; while(cur < vec.size()) { last = vec.size(); pos.push_back(Pos(cur, last)); //记录当前层的起止位置 while(cur < last) //遍历当前层的结点,将子女放入数组中 { if(vec[cur]->left) //先是左然后是右。如果希望自由向左,交换一下顺序即可 vec.push_back(vec[cur]->left); if(vec[cur]->right) vec.push_back(vec[cur]->right); cur++; } level++; //层数加1 } for(int i = level - 1; i >= 0; i--) //自下往上遍历 { for(int j = pos[i].begin; j < pos[i].end; j++) cout<<vec[j]->value<<' '; cout<<endl; } }
本人享有博客文章的版权,转载请标明出处 http://blog.csdn.net/wuzhekai1985