【剑指offer】二叉树的镜像

转载请注明出处:http://blog.csdn.net/ns_code/article/details/25915971

题目描述:

输入一个二叉树,输出其镜像。

输入:

输入可能包含多个测试样例,输入以EOF结束。
对于每个测试案例,输入的第一行为一个整数n(0<=n<=1000,n代表将要输入的二叉树节点的个数(节点从1开始编号)。接下来一行有n个数字,代表第i个二叉树节点的元素的值。接下来有n行,每行有一个字母Ci。
Ci=’d’表示第i个节点有两子孩子,紧接着是左孩子编号和右孩子编号。
Ci=’l’表示第i个节点有一个左孩子,紧接着是左孩子的编号。
Ci=’r’表示第i个节点有一个右孩子,紧接着是右孩子的编号。
Ci=’z’表示第i个节点没有子孩子。

输出:

对应每个测试案例,
按照前序输出其孩子节点的元素值。
若为空输出NULL。

样例输入:
7
8 6 10 5 7 9 11
d 2 3
d 4 5
d 6 7
z
z
z
z
样例输出:
8 10 11 9 6 7 5

这道题目与上道题目一样,采用数组来作为保存二叉树节点的数据结构,会使测试代码更容易编写。具体的实现算法在代码中比较容易看懂,不细说了,主要想说下,测试时遇到的一些问题(最后AC了):

    1、先序遍历的输出要符合要求的格式,即对于每一个测试用例来说,输出的各节点元素间要有一个空格,且输出最后一个元素后要没有空格,但要输出一个换行符,这就要判断出程序什么时候遍历输出最后一个元素,再递归实现的先序遍历函数中,我没想到能使最后一个元素符合输出格式的方法,因此我这里定义了一个int数组,用来顺序保存先序遍历的节点的data,这样直接遍历输出该int数组即可,并再循环输出中判断要输出的元素是不是最后一个输出元素,如果是,就加上换行符。

2、由于要输入字符,因此要考虑输入缓冲队列的问题,每行含有字符的数据输入后,会留下换行符,这样会在下次输入字符时被读取,造成读取字符的错误,因此在下一行数据开始输入前,要刷新缓冲区,刚开始图方面,用了fflush(stdin),在VC++上测试通过了,但是在九度OJ上报了RE,只有一组测试用例通过,多次测试了几组数据之后,怀疑应该是fflush(stdin)的错误,因为有印象在C primer plus上说过,这不是C语言标准里的东西,想gcc应该不支持,后来在网上查了下,gcc是不支持的,这是微软在自家编译器里加的,因此果断用while--getchar()来代替,替换后果然AC了,哎!还是水啊,想想离校招还有不到4个月,心里就没底!

    AC代码:
#include<stdio.h>
#include<stdlib.h>

typedef struct BTNode
{
	int data;
	int rchild;
	int lchild;
}BTNode;

/*
判断pTree1是否包含pTree2
*/
void MirrorTree(BTNode *pTree,int index)
{
	if(pTree == NULL)
		return;
	if(index == -1)
		return;
	if(pTree[index].lchild==-1 && pTree[index].rchild==-1)
		return;

	int temp = pTree[index].lchild;
	pTree[index].lchild = pTree[index].rchild;
	pTree[index].rchild = temp;

	if(pTree[index].lchild!=-1)
		MirrorTree(pTree,pTree[index].lchild);
	if(pTree[index].rchild!=-1)
		MirrorTree(pTree,pTree[index].rchild);
}

//这里设置全局变量i的目的是为了将先序遍历到的元素依次保存到数组preTraverse中,
//其目的是为了确定最后一个输出元素,这样好调整输出的格式,使输出符合测试系统的要求。
int i = 0;
void pre_traverse(BTNode *pTree,int index,int *preTraverse,int n)
{
	if(pTree == NULL)
		return;
	if(index != -1 && i<n)
	{
		preTraverse[i++] = pTree[index].data;
		if(pTree[index].lchild != -1)
			pre_traverse(pTree,pTree[index].lchild,preTraverse,n);
		if(pTree[index].rchild != -1)
			pre_traverse(pTree,pTree[index].rchild,preTraverse,n);
	}
}

int main()
{
	int n;
	while(scanf("%d",&n) != EOF)
	{
		//输入树pTree各节点的值
		BTNode *pTree = NULL;
		if(n>0)
		{
			pTree = (BTNode *)malloc(n*sizeof(BTNode));
			if(pTree == NULL)
				exit(EXIT_FAILURE);
			int i,data;
			//输入n个节点的data
			for(i=0;i<n;i++)
			{
				scanf("%d",&data);
				pTree[i].data = data;
				pTree[i].rchild = -1;
				pTree[i].lchild = -1;
			}

			//输入n行节点连接关系
			for(i=0;i<n;i++)
			{
				char ci;
				//这两行的作用是为了跳过缓冲区中的换行符
				//这里不能用fflush(stdin),gcc不支持,这只是一些编译器自加的,
				//如果用了,测试系统会报RE。
				while(getchar() != ‘\n‘)
					continue;
				scanf("%c",&ci);
				if(ci == ‘z‘)
					continue;
				else if(ci == ‘l‘)
				{
					int lindex;
					scanf("%d",&lindex);
					pTree[i].lchild = lindex-1;
				}
				else if(ci == ‘r‘)
				{
					int rindex;
					scanf("%d",&rindex);
					pTree[i].rchild = rindex-1;
				}
				else if(ci == ‘d‘)
				{
					int lindex,rindex;
					scanf("%d",&lindex);
					scanf("%d",&rindex);
					pTree[i].lchild = lindex-1;
					pTree[i].rchild = rindex-1;
				}
			}
		}

		if(n == 0)
		{
			printf("NULL\n");
			continue;
		}
		MirrorTree(pTree,0);
		//先将遍历的元素依次保存到preTraverse数组中
		int *preTraverse = (int *)malloc(n*sizeof(int));
		if(preTraverse == NULL)
			exit(EXIT_FAILURE);
		pre_traverse(pTree,0,preTraverse,n);
		int i;
		for(i=0;i<n;i++)
		{
			//是输出符合测试系统要求的格式
			if(i == n-1)
				printf("%d\n",preTraverse[i]);
			else
				printf("%d ",preTraverse[i]);
		}

		free(preTraverse);
		preTraverse = NULL;

		free(pTree);
		pTree = NULL;
	}
	return 0;
}

/**************************************************************

    Problem: 1521

    User: mmc_maodun

    Language: C

    Result: Accepted

    Time:0 ms

    Memory:916 kb

****************************************************************/

写点小插曲:今天AC了这道题后,顺道去科技楼看了下电影《年少轻狂》的拍摄,剧组进驻学校拍摄已经有一周多了,偶尔会在校园的某个地方碰到一些戏份的拍摄,这些天的晚上一直在科技楼前拍南海大学(剧中虚拟的大学)毕业舞会的镜头,虽说实验室就在科技楼,但晚上在图书馆自习,所以一直没去看过,今晚突发奇想,跑去瞄了两眼,听周围人说,前面领舞的女的就是陈妍希,我怎么看都看不出来,楼底下更是停了各种豪车:保时捷跑车、宾利老爷车。。。。尼玛演员、导演就是有钱,我等屌丝敲十几年代码都敲不出一辆宾利来,人家一部戏下来,神马都有了!

过来瞄几眼,就把我今天的跑步给耽误了,那是别人的舞台,与我无关,回去继续敲代码。。。。。。

【剑指offer】二叉树的镜像,布布扣,bubuko.com

时间: 2024-10-28 20:28:44

【剑指offer】二叉树的镜像的相关文章

剑指Offer 二叉树的镜像

题目描述 操作给定的二叉树,将其变换为源二叉树的镜像. 输入描述: 二叉树的镜像定义:源二叉树 8 / 6 10 / \ / 5 7 9 11 镜像二叉树 8 / 10 6 / \ / 11 9 7 5 思路: 直接一个中间指针,递归,交换左右节点,节点为叶子节点的时候返回. AC代码: 1 class Solution { 2 public: 3 void Mirror(TreeNode *pRoot) { 4 if(pRoot==NULL) 5 return ; 6 7 TreeNode *

剑指offer——二叉树的镜像

题目描述 操作给定的二叉树,将其变换为源二叉树的镜像. 输入描述: 二叉树的镜像定义:源二叉树 8 / 6 10 / \ / 5 7 9 11 镜像二叉树 8 / 10 6 / \ / 11 9 7 5 代码实现(Java) 1 /** 2 public class TreeNode { 3 int val = 0; 4 TreeNode left = null; 5 TreeNode right = null; 6 7 public TreeNode(int val) { 8 this.val

剑指offer二叉树的镜像python

题目描述 操作给定的二叉树,将其变换为源二叉树的镜像. 输入描述: 二叉树的镜像定义:源二叉树 8 / 6 10 / \ / 5 7 9 11 镜像二叉树 8 / 10 6 / \ / 11 9 7 5 思路 用递归的方法,根节点不变,左子右子交换即可,然后分别递归左右子 代码 # -*- coding:utf-8 -*- # class TreeNode: # def __init__(self, x): # self.val = x # self.left = None # self.rig

剑指offer——二叉树镜像

操作给定的二叉树,将其变换为源二叉树的镜像. 输入描述: 二叉树的镜像定义:源二叉树 8 / \ 6 10 / \ / \ 5 7 9 11 镜像二叉树 8 / \ 10 6 / \ / \ 11 9 7 5 代码如下: /** public class TreeNode { int val = 0; TreeNode left = null; TreeNode right = null; public TreeNode(int val) { this.val = val; } } */ imp

剑指Offer二叉树的深度

package Tree; import java.util.LinkedList; import java.util.Queue; /** * 二叉树的深度 * 输入一棵二叉树,求该树的深度. * 从根结点到叶结点依次经过的结点(含根.叶结点)形成树的一条路径,最长路径的长度为树的深度. */ public class Solution13 { public static void main(String[] args) { int[] array = {1, 2, 3, 4, 5, 6, 7

剑指:二叉树的镜像

题目描述 输入一个二叉树,将它变换为它的镜像. 输入树: 8 / 6 10 / \ / 5 7 9 11 [8,6,10,5,7,9,11,null,null,null,null,null,null,null,null] 输出树: 8 / 10 6 / \ / 11 9 7 5 [8,10,6,11,9,7,5,null,null,null,null,null,null,null,null] 解法 将根结点的左右孩子互换,之后递归左右孩子. /** * Definition for a bina

剑指offer 二叉树的下一个结点

题目描述 给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回.注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针. 思路: 1)如果一个节点有右子树,那么它的下一个结点就是它的右子树中的最左子节点: 2)如果一个节点没有右子树,并且它还是它父节点的右子节点,我们可以沿着指向父节点的指针一直向上遍历,知道找到一个是它父节点的右子节点的左子节点的节点,就是第一个向右转的子部分根节点. /* struct TreeLinkNode { int val; struct Tr

剑指Offer17 二叉树的镜像

1 /************************************************************************* 2 > File Name: 17_MirrorOfBinaryTree.cpp 3 > Author: Juntaran 4 > Mail: [email protected] 5 > Created Time: 2016年08月30日 星期二 17时10分03秒 6 ******************************

剑指Offer——二叉树的下一个结点

题目描述: 给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回.注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针. 分析: 如果该结点存在右子树,那么返回右子树的最左结点. 如果该结点不存在右子树,那么如果该结点不是其父结点的最右结点,那么返回父结点:否则一直找到最大子树的最右结点是该结点,那么返回该最大子树的根结点的父结点. 代码: 1 /* 2 struct TreeLinkNode { 3 int val; 4 struct TreeLinkNode *le

剑指Offer——二叉树的深度

1.题目描述 输入一棵二叉树,求该树的深度.从根结点到叶结点依次经过的结点(含根.叶结点)形成树的一条路径,最长路径的长度为树的深度. 2.代码实现 public int TreeDepth(TreeNode root) { if (root == null) { return 0; } int left_len = TreeDepth(root.left); int right_len = TreeDepth(root.right); return Math.max(left_len, rig