剑指Offer:面试题19 二叉树的镜像

/*
二叉树的镜像:
请完成一个函数,输入一个二叉树,该函数输出它的镜像。


输入:
输入可能包含多个测试样例,输入以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


关键:
递归的出口是:节点值为空
递归主体:
如果当前节点有左孩子和右孩子,则互相交换;
如果该节点只有一个孩子(左或者右),直接称为该节点另一个孩子
需要重新建一棵树吗?还是在原有已经建好树的基础上修改。
因为修改只涉及到子父节点的指向问题,因此不需要重新建树。
Node* left = root->_left;Node* right = root->_right;
root->_left = right;root->_right = left;
*/


/*
关键:
1 cin >> ch;//注意,scanf接受%c时,不会过滤空格,其他控制字符会过滤。10为换行,13为回车。下次碰到字符,立即用C++,别用C
2 if(pHead->_left == NULL && pHead->_right == NULL)//对于左右孩子均为空的情况,直接返回
{
return;
}
3 TreeNode* pLeft = pHead->_left;//接下来不管左右孩子是否一个为空还是均不空,都需要赋值,否则就出错了
pHead->_left = pHead->_right;
pHead->_right = pLeft;
if(pHead->_left)//如果左子树不空,递归遍历左子树
{
binaryTreeMirrorImage(pHead->_left);
}
*/


#include <stdio.h>
#include <string.h>
#include <iostream>
const int MAXSIZE = 1002;


using namespace std;


typedef struct TreeNode
{
int _iVal;
TreeNode* _left;
TreeNode* _right;
}TreeNode;
TreeNode nodeArr[MAXSIZE];
int _iIndex;
TreeNode* createNode()
{
++_iIndex;
nodeArr[_iIndex]._left = nodeArr[_iIndex]._right = NULL;
return &nodeArr[_iIndex];
}




void buildTree(TreeNode** pHead,int* pArr,int n)
{
if(pHead == NULL || *pHead == NULL || pArr == NULL || n < 0 || n > 1000)
{
return;
}
//对每个节点进行赋值
for(int j = 0 ; j < n ;j++)
{
if(j)//对其余节点赋值
{
TreeNode* pNode = createNode();
pNode->_iVal = pArr[j];
}
else//对头结点赋值
{
(*pHead)->_iVal = pArr[j];
}
}
int iLeft,iRight;
for(int i = 1 ; i <= n ; i++)//建立父子结点之间的指向
{
char ch;
cin >> ch;//注意,scanf接受%c时,不会过滤空格,其他控制字符会过滤。10为换行,13为回车。下次碰到字符,立即用C++,别用C
//while((ch = getchar()) && (ch == '\n' || ch == (char)10) || ch == ' '){}
//printf("%c",ch);
switch (ch)
{
case 'd':
scanf("%d %d",&iLeft,&iRight);
nodeArr[i]._left = &nodeArr[iLeft];
nodeArr[i]._right = &nodeArr[iRight];
break;
case 'l':
scanf("%d",&iLeft);
nodeArr[i]._left = &nodeArr[iLeft];
break;
case 'r':
scanf("%d",&iRight);
nodeArr[i]._right = &nodeArr[iRight];
break;
case 'z':
break;
default:
break;
}
}
}


void binaryTreeMirrorImage(TreeNode* pHead)
{
if(pHead == NULL)//递归出口
{
return;
}
if(pHead->_left == NULL && pHead->_right == NULL)//对于左右孩子均为空的情况,直接返回
{
return;
}
TreeNode* pLeft = pHead->_left;//接下来不管左右孩子是否一个为空还是均不空,都需要赋值,否则就出错了
pHead->_left = pHead->_right;
pHead->_right = pLeft;
if(pHead->_left)//如果左子树不空,递归遍历左子树
{
binaryTreeMirrorImage(pHead->_left);
}
if(pHead->_right)
{
binaryTreeMirrorImage(pHead->_right);
}
}


bool isFirst;
void frontVisit(TreeNode* pHead)
{
if(pHead == NULL)//递归出口
{
return;
}
if(!isFirst)//不是第一次进入
{
printf(" %d",pHead->_iVal);
}
else//第一次进入
{
printf("%d",pHead->_iVal);
isFirst = false;
}
frontVisit(pHead->_left);
frontVisit(pHead->_right);
}


void process()
{
int n;
while(EOF != scanf("%d",&n))
{
if(n < 0 || n > 1000)
{
printf("NULL\n");
continue;
}
int iArr[MAXSIZE];
for(int i = 0 ; i < n ; i++)
{
scanf("%d",&iArr[i]);
}
_iIndex = 0;
memset(nodeArr,NULL,sizeof(nodeArr));
TreeNode* head = createNode();
TreeNode** pHead = &head;
buildTree(pHead,iArr,n);
binaryTreeMirrorImage(head);
isFirst = true;
frontVisit(head);
printf("\n");
}
}


int main(int argc,char* argv[])
{
process();
getchar();
return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值