【剑指Offer面试编程题】题目1521:二叉树的镜像--九度OJ
- 输入:
-
输入可能包含多个测试样例,输入以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【解题思路】这道题目的思路应该还是比较清晰的,这里所谓的镜像无非就是树的所有的节点的左右子树对调。要求输出镜像树的先序遍历,我们很容易想到只需要将正常树的前序遍历算法稍作修改即可。只需要将遍历顺序:根-左-右,变为:根-右-左。即可完成任务。
当然前面的数据输入,建树的过程就不做多说了,应该还是比较简单的。中间需要利用set数据结构寻找到根节点的编号,因为根节点不会出现在输入的子节点中,所以也很好找出来。
AC code:
#include <cstdio> #include <vector> #include <set> using namespace std; struct st { int val; st*lc,*rc; }; void print(st*s) { printf(" %d",s->val); if(s->rc!=NULL) print(s->rc); if(s->lc!=NULL) print(s->lc); } int main() { int n; while(scanf("%d",&n)!=EOF) { if(n==0) printf("NULL "); else { vector<st> vec; st ss; ss.val=-1; ss.lc=ss.rc=NULL; vec.push_back(ss); set<int> treeidx; for(int ii=0;ii<n;++ii) { int tt; scanf("%d",&tt); ss.val=tt; vec.push_back(ss); treeidx.insert(ii+1); } for(int i=1;i<=n;++i) { char c[2]; int l,r; scanf("%s",c); switch(c[0]){ case 'd': scanf("%d%d",&l,&r); treeidx.erase(l); treeidx.erase(r); vec[i].lc=&vec[l]; vec[i].rc=&vec[r]; break; case 'l': scanf("%d",&l); treeidx.erase(l); vec[i].lc=&vec[l]; break; case 'r': scanf("%d",&r); treeidx.erase(r); vec[i].rc=&vec[r]; break; case 'z': break; default: break; } } set<int>::iterator it=treeidx.begin(); printf("%d",vec[*it].val); if(vec[*it].rc!=NULL) print(vec[*it].rc); if(vec[*it].lc!=NULL) print(vec[*it].lc); printf(" "); } } return 0; } /************************************************************** Problem: 1521 User: huo_yao Language: C++ Result: Accepted Time:0 ms Memory:1028 kb ****************************************************************/题目链接:http://ac.jobdu.com/problem.php?pid=1521九度-剑指Offer习题全套答案下载:http://download.****.net/detail/huoyaotl123/8276299