1102 Invert a Binary Tree (25 分)

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

给出二叉树的各个节点的左右孩子结点,反转二叉树,输出层序和中序。本题用静态存储,下标既是地址又是数据data.

建树的时候直接反过来存储就不用写反转的代码了

直接反过来存储

#include<bits/stdc++.h>
using namespace std;

struct node{
// int data;//没用 下标就是data 空结点下标都是-1
int lchild,rchild;
}Node[20];//Node数组才是二叉树 下标是地址 data和下标相等 题目设置得好可以这么做

int toInt(char c){
if(c=='-') return -1;
else return c-'0';
}

bool firstIn=true;
void inOrder(int root){
if(root==-1) return;
inOrder(Node[root].lchild);
if(!firstIn) cout<<" ";
else firstIn=false;
cout<<root;
inOrder(Node[root].rchild);
}

void layerOrder(int root){
queue<int> q;
q.push(root);
bool first=true;
while(!q.empty()){
int top=q.front();
q.pop();
if(!first) cout<<" ";
else first=false;
cout<<top;
if(Node[top].lchild!=-1) q.push(Node[top].lchild);
if(Node[top].rchild!=-1) q.push(Node[top].rchild);
}
cout<<endl;
}


int main(){
// freopen("in.txt","r",stdin);
int n;
char l,r;
bool hasParent[20]={0};//0表示没有父节点 也即是根结点 1表示有父结点,则不是根结点
cin>>n;
for(int i=0;i<n;i++){
cin>>l>>r;
if(l=='-') Node[i].rchild=-1;
else{
Node[i].rchild=l-'0';
hasParent[l-'0']=true;
}

if(r=='-') Node[i].lchild=-1;
else{
Node[i].lchild=r-'0';
hasParent[r-'0']=true;
}
}
//找根
int root;
for(root=0;root<n;root++){
if(!hasParent[root]) break;
}
layerOrder(root);
inOrder(root);
return 0;
}

正过来正常存储,额外写反转代码(就是后序遍历,遍历到根结点时swap(lchild,rchild)即可,因为遍历root前rchild和lchild一定便利过了,所以后序遍历过程中改正好能行,不会影响后边的遍历进行)

#include<bits/stdc++.h>
using namespace std;

struct node{
// int data;//没用 下标就是data 空结点下标都是-1
int lchild,rchild;
}Node[20];//Node数组才是二叉树 下标是地址 data和下标相等 题目设置得好可以这么做

int toInt(char c){
if(c=='-') return -1;
else return c-'0';
}

bool firstIn=true;
void inOrder(int root){
if(root==-1) return;
inOrder(Node[root].lchild);
if(!firstIn) cout<<" ";
else firstIn=false;
cout<<root;
inOrder(Node[root].rchild);
}

void layerOrder(int root){
queue<int> q;
q.push(root);
bool first=true;
while(!q.empty()){
int top=q.front();
q.pop();
if(!first) cout<<" ";
else first=false;
cout<<top;
if(Node[top].lchild!=-1) q.push(Node[top].lchild);
if(Node[top].rchild!=-1) q.push(Node[top].rchild);
}
cout<<endl;
}

void postInvert(int root){
if(root==-1) return;
postInvert(Node[root].lchild);
postInvert(Node[root].rchild);
//访问root结点,此时逻辑是反转左右孩子
swap(Node[root].lchild,Node[root].rchild);
}


int main(){
freopen("in.txt","r",stdin);
int n;
char l,r;
bool hasParent[20]={0};//0表示没有父节点 也即是根结点 1表示有父结点,则不是根结点
cin>>n;
for(int i=0;i<n;i++){
cin>>l>>r;
if(l=='-') Node[i].lchild=-1;
else{
Node[i].lchild=l-'0';
hasParent[l-'0']=true;
}

if(r=='-') Node[i].rchild=-1;
else{
Node[i].rchild=r-'0';
hasParent[r-'0']=true;
}
}
//找根
int root;
for(root=0;root<n;root++){
if(!hasParent[root]) break;
}
//反转
postInvert(root);
//输出
layerOrder(root);
inOrder(root);
return 0;
}