http://pat.zju.edu.cn/contests/pat-a-practise/1043
给予N个数字组成二叉搜索树,判断这个数列是否由先序遍历得出或是镜像先序遍历得出,若是则输出相应的后续遍历或是镜像后续遍历
分析:
镜像先序遍历其实就是 先访问祖先,再访问右子树,再左子树
镜像后续遍历就是先访问右子树,再左子树,在祖先
#include<stdio.h> struct tree{ int v; tree *left,*right; }; int shu[1099]; int pre[1099]; int post[1099]; int step; void bulid(tree* head,int v){ if(v >= head->v){ if(head->right==NULL){ head->right=new tree; head=head->right; head->v=v; head->left=NULL; head->right=NULL; }else{ bulid(head->right,v); } }else{ if(head->left==NULL){ head->left=new tree; head=head->left; head->v=v; head->left=NULL; head->right=NULL; }else{ bulid(head->left,v); } } } void preTree(tree* head,int mirror){ pre[step]=head->v; step++; if(mirror==0){ if(head->left!=NULL)preTree(head->left,mirror); if(head->right!=NULL)preTree(head->right,mirror); }else{ if(head->right!=NULL)preTree(head->right,mirror); if(head->left!=NULL)preTree(head->left,mirror); } } void postTree(tree* head,int mirror){ if(mirror==0){ if(head->left!=NULL)postTree(head->left,mirror); if(head->right!=NULL)postTree(head->right,mirror); }else{ if(head->right!=NULL)postTree(head->right,mirror); if(head->left!=NULL)postTree(head->left,mirror); } post[step]=head->v; step++; } int main(){ int n; while(scanf("%d",&n)!=EOF){ int i,mirror=-1; tree* rhead; tree* head=new tree; rhead=head; for(i=1;i<=n;i++){ scanf("%d",&shu[i]); } if(n==1){ printf("YES "); printf("%d ",shu[1]); continue; } head->v=shu[1]; head->left=NULL; head->right=NULL; for(i=2;i<=n;i++){ bulid(rhead,shu[i]); } step=1; preTree(rhead,0);//普通的先序遍历 for(i=1;i<=n;i++){ if(shu[i]!=pre[i])break; } if(i==n+1)mirror=0; step=1; preTree(rhead,1);//镜像先序遍历 for(i=1;i<=n;i++){ if(shu[i]!=pre[i])break; } if(i==n+1)mirror=1; if(mirror==-1){ printf("NO "); continue; } printf("YES "); step=1; postTree(rhead,mirror); int ok=0; for(i=1;i<=n;i++){ if(ok==0)ok=1; else printf(" "); printf("%d",post[i]); } printf(" "); } return 0; }