A1102. Invert a Binary Tree

The following is from Max Howell @twitter:

Google: 90% of our engineers use the software you wrote (Homebrew), but you can't invert a binary tree on a whiteboard so fuck off.

Now it's your turn to prove that YOU CAN invert a binary tree!

Input Specification:

Each input file contains one test case. For each case, the first line gives a positive integer N (<=10) which is the total number of nodes in the tree -- and hence the nodes are numbered from 0 to N-1. Then N lines follow, each corresponds to a node from 0 to N-1, and gives the indices of the left and right children of the node. If the child does not exist, a "-" will be put at the position. Any pair of children are separated by a space.

Output Specification:

For each test case, print in the first line the level-order, and then in the second line the in-order traversal sequences of the inverted tree. There must be exactly one space between any adjacent numbers, and no extra space at the end of the line.

Sample Input:

8
1 -
- -
0 -
2 7
- -
- -
5 -
4 6

Sample Output:

3 7 2 6 4 0 5 1
6 5 7 4 3 2 0 1

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<stack>
 4 #include<string.h>
 5 #include<queue>
 6 using namespace std;
 7 typedef struct NODE{
 8     int lchild, rchild;
 9     int data;
10 }node;
11 node tree[11];
12 int N, notRoot[11] = {0,0};
13 void postReverse(int root){
14     if(root == -1)
15         return;
16     if(tree[root].lchild != -1)
17         postReverse(tree[root].lchild);
18     if(tree[root].rchild != -1)
19         postReverse(tree[root].rchild);
20     swap(tree[root].lchild, tree[root].rchild);
21 }
22 void levelOrder(int root, int &cnt){
23     queue<int> Q;
24     if(root != -1){
25         Q.push(root);
26     }
27     while(Q.empty() == false){
28         int index = Q.front();
29         Q.pop();
30         cnt++;
31         if(cnt == N){
32             printf("%d", tree[index].data);
33         }else{
34             printf("%d ", tree[index].data);
35         }
36         if(tree[index].lchild != -1)
37             Q.push(tree[index].lchild);
38         if(tree[index].rchild != -1)
39             Q.push(tree[index].rchild);
40     }
41 }
42 void inOrder(int root, int &cnt){
43     if(root == -1)
44         return;
45     if(tree[root].lchild != -1)
46         inOrder(tree[root].lchild, cnt);
47     cnt++;
48     if(cnt == N)
49         printf("%d", tree[root].data);
50     else printf("%d ", tree[root].data);
51     if(tree[root].rchild != -1)
52         inOrder(tree[root].rchild, cnt);
53 }
54 int main(){
55     char c1, c2;
56     scanf("%d", &N);
57     for(int i = 0; i < N; i++){
58         scanf("%*c%c %c", &c1, &c2);
59         if(c1 == '-'){
60             tree[i].lchild = -1;
61         }else{
62             tree[i].lchild = c1 - '0';
63             notRoot[c1 - '0'] = 1;
64         }
65         if(c2 == '-'){
66             tree[i].rchild = -1;
67         }else{
68             tree[i].rchild = c2 - '0';
69             notRoot[c2 - '0'] = 1;
70         }
71         tree[i].data = i;
72     }
73     int root = 0;
74     for(int i = 0; i < N; i++)
75         if(notRoot[i] == 0){
76             root = i;
77             break;
78         }
79     int cnt = 0;
80     postReverse(root);
81     levelOrder(root, cnt);
82     printf("\n");
83     cnt = 0;
84     inOrder(root, cnt);
85     cin >> N;
86     return 0;
87 }
View Code

 

总结:

1、本题要求先对二叉树进行反转(左变成右),再层序和中序输出。由于二叉树的后序遍历是先访问左右子树,再访问根节点,与逆转具有相同的性质。逆转要求在左右子树都已经逆转之后,再将这两颗子树交换位置。因此逆转二叉树可以用后序遍历实现。

2、对于给数字编号、给出每个节点的左右孩子编号的输入数据,最好使用静态二叉树。将节点都保存在一个node数组中,仅仅对数组的下标进行操作。

3、静态二叉树寻找root:使用数组notRoot坐标记,在读入节点时,如果将其孩子节点标记为notRoot。输入完毕后遍历数组寻找root节点。

4、由于%c会将上一行的 \n 读入,所以每行之前要吸收 \n, 两个字符之间还要匹配空格。可以 scanf("%*c%c %c", &c1, &c2); 其中%*c会读入一个字符,但被忽略,接收参数的是后两个。

转载于:https://www.cnblogs.com/zhuqiwei-blog/p/8540207.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值