题目来源:PAT (Advanced Level) Practice
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
words:
Invert 使反转,前后倒置 whiteboard 白板 adjacent 邻近的
题意:
将给定的一颗二叉树进行反转,即左右子树互换,然后输出层序遍历序列和中序遍历序列;
思路:
1. 本题的输入使以左子树 右子树的形式,所以在输入时我们按照右子树 左子树的形式输入,即可实现反转效果;
2. 用一个二维数组a[][2]来保存二叉树,行下标代表根结点,每行的两个元素分别代表右子树和左子树;
3. 用一个一维数组vis[]来保存一个结点是否为其他结点的孩子结点,下标代表结点;
4. 在vis[]中找出不是任何结点的孩子结点的结点,即根结点;
6. 从根结点开始进行层序遍历;
7. 从根结点开始进行中序遍历;
//PAT ad 1102 Invert a Binary Tree
#include <iostream>
using namespace std;
#define N 10
#include <queue>
char a[N][2];
bool vis[N]={false};
string ans_InOrder; //前序遍历结果
string ans_level; //层序遍历结果
void InOrder(int i) //前序遍历
{
if(a[i][0]!='-'&&a[i][1]!='-') //左右子树均非空
{
InOrder(a[i][1]-'0'); //递归遍历左子树
ans_InOrder+=to_string(i)+" "; //输出当前根结点
InOrder(a[i][0]-'0'); //递归遍历右子树
}
else if(a[i][1]!='-') //左子树非空
{
InOrder(a[i][1]-'0');
ans_InOrder+=to_string(i)+" ";
}
else if(a[i][0]!='-') //右子树非空
{
ans_InOrder+=to_string(i)+" ";
InOrder(a[i][0]-'0');
}
else
ans_InOrder+=to_string(i)+" "; //左右子都为空
}
void Level(int i) //层序遍历
{
queue<int> que;
que.push(i); //压入根结点
while(!que.empty())
{
int x=que.front();que.pop();
ans_level+=to_string(x)+" ";
if(a[x][1]!='-') //判断左子树
que.push(a[x][1]-'0');
if(a[x][0]!='-') //判断右子树
que.push(a[x][0]-'0');
}
}
int main()
{
int n,i;
cin>>n;
char r,l;
for(i=0;i<n;i++)
{
cin>>r>>l; //右子树、左子树
a[i][0]=r;a[i][1]=l;
if(r>='0'&&r<='9')
vis[r-'0']=true; //标记是否为某个树的子节点
if(l>='0'&&l<='9')
vis[l-'0']=true;
}
for(i=0;i<n;i++) //寻找根结点
if(vis[i]==false)
break;
Level(i); //层序遍历
InOrder(i); //前序遍历
ans_level.pop_back(); //舍弃末尾空格
ans_InOrder.pop_back();
cout<<ans_level<<endl; //输出
cout<<ans_InOrder<<endl;
return 0;
}