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

来源:互联网 发布:java string 添加元素 编辑:程序博客网 时间:2024/05/22 09:41
/*二叉树的镜像:请完成一个函数,输入一个二叉树,该函数输出它的镜像。输入:输入可能包含多个测试样例,输入以EOF结束。对于每个测试案例,输入的第一行为一个整数n(0<=n<=1000,n代表将要输入的二叉树节点的个数(节点从1开始编号)。接下来一行有n个数字,代表第i个二叉树节点的元素的值。接下来有n行,每行有一个字母Ci。Ci=’d’表示第i个节点有两子孩子,紧接着是左孩子编号和右孩子编号。Ci=’l’表示第i个节点有一个左孩子,紧接着是左孩子的编号。Ci=’r’表示第i个节点有一个右孩子,紧接着是右孩子的编号。Ci=’z’表示第i个节点没有子孩子。输出:对应每个测试案例,按照前序输出其孩子节点的元素值。若为空输出NULL。样例输入:78 6 10 5 7 9 11d 2 3d 4 5d 6 7zzzz样例输出: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++,别用C2 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
原创粉丝点击