【PAT】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. 重复的不再这里累述,有点问题的是对静态树缺乏使用的经验,另外对反转树理解不是很透彻
  2. 用后序序列反转列表优于先序序列
  3. scanf("%*c");可以在scanf中接收一个字符,在本题中吃掉上一行的换行符,否则%c会被输入换行符,这个要注意,也可以用getchar()吃掉换行符。在用%c输入的时候尤其要注意换行符不能被插入

代码:

#include <stdio.h>
#include <queue>
using namespace std;
const int maxn=110;
int total;
bool  check[maxn]={false};
struct Node{
	int lchild;
	int rchild;
}node[maxn];

int strTonum(char c){  //字符转化为数组 
	if(c=='-') return -1;
	else{
		check[c-'0']=true;
		return c-'0';
	}
}

int foundRoot(){  //找到根结点 
	for(int i=0;i<total;i++){
		if(check[i]==false) return i;
	}
}


int num=0; //当前输出的个数 
void print(int x){  //输出 
	printf("%d",x);
	num++;
	if(num<total) printf(" ");
	else printf("\n");
}
void BFS(int root){  //层序遍历 
	queue<int> q;
	q.push(root);
	while(!q.empty()){
		int x=q.front();
		q.pop();
		print(x);
		if(node[x].lchild!=-1) q.push(node[x].lchild);
		if(node[x].rchild!=-1) q.push(node[x].rchild);
	}
}
void inOrder(int root){  //中序遍历 
	if(root==-1) return;
	inOrder(node[root].lchild);
	print(root);
	inOrder(node[root].rchild);
}
void postOrder(int root){  //后序遍历用于反转二叉树 
	if(root==-1) return;
	postOrder(node[root].lchild);
	postOrder(node[root].rchild);
	swap(node[root].lchild,node[root].rchild);  //交换左右孩子结点 
}  

int main(){
	scanf("%d",&total);
	char lchild,rchild;
	for(int i=0;i<total;i++){
		scanf("%*c%c %c",&lchild,&rchild);  //%*c吃掉上一行的换行符 ,因为%c也会把空格输入 
		node[i].lchild=strTonum(lchild);
		node[i].rchild=strTonum(rchild);
	}
	int root=foundRoot();
	postOrder(root);  //后序遍历反转二叉树 
	BFS(root); 
	num=0;
	inOrder(root);
	return 0;
}

 

1本程序在vc++6.0编译通过并能正常运行。 2主界面 程序已经尽量做到操作简便了,用户只需要根据提示一步步进行操作就行了。 六思考和总结: 这个课程设计的各个基本操作大部分都在我的综合性实验中实现了,所以做这个主要攻克插入和删除这两个算法!其中插入在书本上已经有了,其中的右平衡算法虽然没有给出,但通过给出的左平衡算法很容易就可以写出右平衡算法。所以最终的点就在于删除算法的实现!做的过程中对插入算法进行了非常非常多次的尝试!花了非常多的时间,这其中很多时候是在对程序进行单步调试,运用了VC6。0的众多良好工具,也学到了很多它的许多好的调试手段。 其中删除算法中最难想到的一点是:在用叶子结点代替要删除的非叶子结点后,应该递归的运用删除算法去删除叶子结点!这就是整个算法的核心,其中很强烈得体会到的递归的强大,递归的最高境界(我暂时能看到的境界)! 其它的都没什么了。选做的那两个算法很容易实现的: 1合并两棵平衡二叉排序:只需遍历其中的一棵,将它的每一个元素插入到另一棵即可。 2拆分两棵平衡二叉排序:只需以根结点为中心,左子独立为一棵,右子独立为一棵,最后将根插入到左子或右子即可。 BSTreeEmpty(BSTree T) 初始条件:平衡二叉排序存在。 操作结果:若T为空平衡二叉排序,则返回TRUE,否则FALSE. BSTreeDepth(BSTree T) 初始条件:平衡二叉排序存在。 操作结果:返回T的深度。 LeafNum(BSTree T) 求叶子结点数,非递归中序遍历 NodeNum(BSTree T) 求结点数,非递归中序遍历 DestoryBSTree(BSTree *T) 后序遍历销毁平衡二叉排序T R_Rotate(BSTree *p) 对以*p为根的平衡二叉排序作右旋处理,处理之后p指向新的根结点 即旋转处理之前的左子的根结点 L_Rotate(BSTree *p) 对以*p为根的平衡二叉排序作左旋处理,处理之后p指向新的根结点, 即旋转处理之前的右子的根结点 LeftBalance(BSTree *T) 对以指针T所指结点为根的平衡二叉排序作左平衡旋转处理, 本算法结束时,指针T指向新的根结点 RightBalance(BSTree *T) 对以指针T所指结点为根的平衡二叉排序作右平衡旋转处理, 本算法结束时,指针T指向新的根结点 Insert_AVL(BSTree *T, TElemType e, int *taller) 若在平衡的二叉排序T中不存在和e有相同的关键字的结点, 则插入一个数据元素为e的新结点,并返回OK,否则返回ERROR. 若因插入而使二叉排序失去平衡,则作平衡旋转处理 布尔变量taller反映T长高与否 InOrderTraverse(BSTree T) 递归中序遍历输出平衡二叉排序 SearchBST(BSTree T, TElemType e, BSTree *f, BSTree *p) 在根指针T所指的平衡二叉排序中递归的查找其元素值等于e的数据元素, 若查找成功,则指针p指向该数据元素结点,并返回TRUE,否则指针p 指向查找路径上访问的最后一个结点并返回FALSE,指针f指向T的双亲, 其初始调用值为NULL Delete_AVL(BSTree *T, TElemType e, int *shorter) 在平衡二叉排序中删除元素值为e的结点,成功返回OK,失败返回ERROR PrintBSTree_GList(BSTree T) 以广义表形式打印出来 PrintBSTree_AoList(BSTree T, int length) 以凹入表形式打印,length初始值为0 Combine_Two_AVL(BSTree *T1, BSTree T2) 合并两棵平衡二叉排序 Split_AVL(BSTree T, BSTree *T1, BSTree *T2) 拆分两棵平衡二叉树 } (2)存储结构的定义: typedef struct BSTNode { TElemType data; int bf; //结点的平衡因子 struct BSTNode *lchild, *rchild;//左.右孩子指针 }BSTNode, *BSTree;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_之桐_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值