1102 Invert a Binary Tree

题目来源: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;
 } 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值