第16题
题目:输入一颗二元树,从上往下按层打印树的每个结点,同一层中按照从左往右的顺序打印。
例如输入
8
/ /
6 10
// //
5 7 9 11
输出8 6 10 5 7 9 11。
题目分析:
从题目中可以看出,要求的遍历顺序不是前序、中序或后序遍历树。树是通过递归定义的,正常递归方法不能实现要求中的遍历顺序。按照要求每次都是从同一层的最左遍历到树的最右。下一层都是按照同一节点的孩子的顺序遍历。如遍历第三层是按照第二层各结点左右孩子的顺序,先遍历6的左右孩子,然后遍历10的左右孩子这样。于是我们想到用一个队列将树上的各个结点缓存起来依次遍历。分析到这里这个问题基本已经解决了。
那么上代码:
#include <stdio.h>
#include <deque>
#include <iostream>
using namespace std;
// 结点
struct Node {
int value;
Node* left;
Node* right;
};
// 二叉树
class BinaryTree {
public:
BinaryTree(Node* root) : m_root(root) { };
~BinaryTree() { };
int levelTraverse();
/* data */
private:
Node* m_root;
deque<Node*> m_queue;
};
// 层序遍历
int BinaryTree::levelTraverse()
{
if (NULL == m_root) {
return -1;
}
m_queue.push_back(m_root);
Node* tmp = m_queue.front();
while(NULL != tmp) {
m_queue.pop_front();
cout<<"value = "<<tmp->value<<endl;
if (NULL != tmp->left) {
m_queue.push_back(tmp->left);
}
if (NULL != tmp->right) {
m_queue.push_back(tmp->right);
}
if (0 < m_queue.size())
{
tmp = m_queue.front();
}
else
{
return -1;
}
}
return 0;
}
测试程序:
// 用于构造树
void Link(Node* obj, int parrent, int left, int right) {
if (-1 != left) {
obj[parrent].left = &obj[left];
}
if (-1 != right) {
obj[parrent].right = &obj[right];
}
return ;
}
int test_16() {
/* tree like:
0
/ \
1 2
/ \ / \
3 4 5 6
/ \
7 8
*/
Node obj_1[9];
memset(obj_1, 0, sizeof(Node)*9);
for (int i = 0; i < 9; i++) {
obj_1[i].value = i;
obj_1[i].left = NULL;
obj_1[i].right = NULL;
}
Link(obj_1, 0, 1, 2);
Link(obj_1, 1, 3, 4);
Link(obj_1, 2, 5, 6);
Link(obj_1, 3, 7, -1);
Link(obj_1, 5, -1, 8);
BinaryTree tree(&obj_1[0]);
if (!tree.levelTraverse()) {
cout<<"error"<<endl;
return -1;
}
return 0;
}
int main(int argc, char const *argv[])
{
test_16();
return 0;
}
测试结果:
//GD bgl-pub2:/home/d5000/kedong/src/platform/personal_test/liyang/practice_alg % ./16th
value = 0
value = 1
value = 2
value = 3
value = 4
value = 5
value = 6
value = 7
value = 8
路漫漫吾修远兮,吾将上下而求索…