剑指Offer - 九度1523 - 从上往下打印二叉树
2013-12-01 00:35
- 题目描述:
-
从上往下打印出二叉树的每个节点,同层节点从左至右打印。
- 输入:
-
输入可能包含多个测试样例,输入以EOF结束。
对于每个测试案例,输入的第一行一个整数n(1<=n<=1000, :n代表将要输入的二叉树元素的个数(节点从1开始编号)。接下来一行有n个数字,代表第i个二叉树节点的元素的值。接下来有n行,每行有一个字母Ci。
Ci=’d’表示第i个节点有两子孩子,紧接着是左孩子编号和右孩子编号。
Ci=’l’表示第i个节点有一个左孩子,紧接着是左孩子的编号。
Ci=’r’表示第i个节点有一个右孩子,紧接着是右孩子的编号。
Ci=’z’表示第i个节点没有子孩子。
- 输出:
-
对应每个测试案例,
按照从上之下,从左至右打印出二叉树节点的值。
- 样例输入:
-
7 8 6 5 7 10 9 11 d 2 5 d 3 4 z z d 6 7 z z
- 样例输出:
-
8 6 10 5 7 9 11
题意分析:
很典型的level-order traversal问题。当我们需要从上至下,从左至右遍历二叉树时,用队列是最好的办法了。思路如下:
1. 初始化时,将根节点push入队
2. 只要队列不为空,就pop出一个元素进行输出,并将这个元素的左右孩子(如果不为空)依次push进队。
3. 队列为空时,算法执行结束。
那么,怎么确定这个算法是对的呢?
首先是从上至下,对于每个节点,都将它的左右孩子入队,两者深度相差1。因此遍历出来的结果中,第n+1层的结果必然紧跟第n层之后。
然后是从左至右,对于每个节点,都是从左至右将子节点入队,所以对于同一层的结果顺序肯定是满足从左至右的。
说实话,写个能ac的代码不算什么大本事,能严格证明自己程序的正确性才是真牛人...或许我读完了《算法导论》后能给这篇文章补上个严格的推理过程。不得不感叹自己还是荒废太多时间了,大学四年都没读几本像样的书,已然二十三岁高龄,老大徒伤悲矣~一万小时却还连一半都没攒到,难怪水平这么菜了。
输入数据要注意:根节点是哪一个,题目并没指定,所以要根据入度来判断哪个才是根,根节点入度为0。
1 // 652502 zhuli19901106 1523 Accepted 点击此处查看所有case的执行结果 1052KB 1528B 0MS 2 // 201311170443 3 #include <cstdio> 4 #include <queue> 5 using namespace std; 6 7 int main() 8 { 9 const int MAXN = 1005; 10 queue<int> qq; 11 int i; 12 int n; 13 int x, y; 14 int r; 15 int a[MAXN][3]; 16 int c[MAXN]; 17 bool first_node; 18 char s[10]; 19 20 while(scanf("%d", &n) == 1){ 21 for(i = 0; i < n; ++i){ 22 scanf("%d", &a[i][0]); 23 c[i] = 0; 24 } 25 for(i = 0; i < n; ++i){ 26 scanf("%s", s); 27 if(s[0] == 'd'){ 28 scanf("%d%d", &x, &y); 29 a[i][1] = x - 1; 30 a[i][2] = y - 1; 31 ++c[x - 1]; 32 ++c[y - 1]; 33 }else if(s[0] == 'l'){ 34 scanf("%d", &x); 35 a[i][1] = x - 1; 36 a[i][2] = -1; 37 ++c[x - 1]; 38 }else if(s[0] == 'r'){ 39 scanf("%d", &y); 40 a[i][1] = -1; 41 a[i][2] = y - 1; 42 ++c[y - 1]; 43 }else{ 44 a[i][1] = a[i][2] = -1; 45 } 46 } 47 48 r = -1; 49 for(i = 0; i < n; ++i){ 50 if(c[i] == 0){ 51 r = i; 52 break; 53 } 54 } 55 if(r < 0){ 56 // invalid tree structure 57 continue; 58 } 59 60 first_node = true; 61 qq.push(r); 62 while(!qq.empty()){ 63 x = qq.front(); 64 qq.pop(); 65 if(first_node){ 66 printf("%d", a[x][0]); 67 first_node = false; 68 }else{ 69 printf(" %d", a[x][0]); 70 } 71 if(a[x][1] != -1){ 72 qq.push(a[x][1]); 73 } 74 if(a[x][2] != -1){ 75 qq.push(a[x][2]); 76 } 77 } 78 printf(" "); 79 80 while(!qq.empty()){ 81 qq.pop(); 82 } 83 } 84 85 return 0; 86 }