【1119】Pre- and Post-order Traversals (30分)

举报
野猪佩奇996 发表于 2022/01/23 22:10:02 2022/01/23
【摘要】 法1 #include <stdio.h>#include <string.h>const int maxn = 10000+5;bool isUnique;int pre[maxn], post[maxn];int left[maxn], right[maxn];int ans[maxn], nodes; /...

法1


  
  1. #include <stdio.h>
  2. #include <string.h>
  3. const int maxn = 10000+5;
  4. bool isUnique;
  5. int pre[maxn], post[maxn];
  6. int left[maxn], right[maxn];
  7. int ans[maxn], nodes;
  8. //return root
  9. int reBuild(int prel, int prer, int postl, int postr) {
  10. if(prel > prer) return -1;
  11. int root = pre[prel];
  12. if(prel == prer) { //leaf
  13. return root;
  14. }
  15. //left-tree
  16. int l1 = prel+1, r2;
  17. for(r2 = postl; r2 < postr; r2++) {//在后序中寻找根结点
  18. if(post[r2] == pre[l1]) {
  19. break;
  20. }
  21. }
  22. int len = r2 - postl + 1;
  23. // check unique
  24. if(len == prer-prel) {
  25. isUnique = false;
  26. //若非叶子结点只有左子树/右子树则不唯一
  27. }
  28. int r1 = l1 + len -1;
  29. int l2 = postl;
  30. //rebulid left-tree
  31. left[root] = reBuild(l1, r1, l2, r2);
  32. //rebuild right-tree
  33. right[root] = reBuild(r1+1, prer, r2+1, prer-1);
  34. return root;
  35. }
  36. void getInorder(int root) {
  37. if(root == -1) return;
  38. getInorder(left[root]);//递归左子树
  39. ans[nodes++] = root;
  40. getInorder(right[root]);//递归右子树
  41. }
  42. int main() {
  43. int n;
  44. while(scanf("%d", &n) == 1) {
  45. isUnique = true;
  46. memset(left, -1, sizeof(left));//赋初值
  47. memset(right, -1, sizeof(right));
  48. for(int i = 0; i < n; i++) {
  49. scanf("%d", &pre[i]);
  50. }
  51. for(int i = 0; i < n; i++) {
  52. scanf("%d", &post[i]);
  53. }
  54. int root = reBuild(0, n-1, 0, n-1);
  55. nodes = 0;
  56. getInorder(root);
  57. if(isUnique) {
  58. printf("Yes\n");
  59. } else {
  60. printf("No\n");
  61. }
  62. for(int i = 0; i < nodes; i++) {
  63. printf("%d%c", ans[i], i == nodes-1 ? '\n' : ' ');
  64. }
  65. }
  66. return 0;
  67. }

法2


  
  1. #include<iostream>
  2. #include<stdio.h>
  3. #include<stdlib.h>
  4. #include<math.h>
  5. #include<string.h>
  6. #include<algorithm>
  7. #include<map>
  8. #include<vector>
  9. #include<queue>
  10. using namespace std;
  11. //确定树唯一:除了叶结点以外的每个结点都有两个孩子
  12. int n,len;
  13. vector<int> pre(10000),post(10000),in(10000);
  14. //int pre[35],post[35],in[35];
  15. int getIn(int prel,int prer,int postl,int postr){
  16. if(prel>prer) return 0;//非法数据
  17. if(prel==prer){
  18. //若遍历左右相等则说明此子树为叶结点~直接加入中序遍历序列
  19. in[++len]=pre[prel];
  20. return 1;
  21. }
  22. int i;
  23. for(i=postl;i<postr;i++){
  24. if(post[i]==pre[prel+1]) break;
  25. }
  26. int ok=1;
  27. ok &= getIn(prel+1,prel+i-postl+1,postl,i);
  28. //递归左子树
  29. in[++len]=pre[prel];
  30. ok &=getIn(prel+i-postl+2,prer,i+1,postr-1);
  31. //递归右子树
  32. return ok;
  33. }
  34. int main(){
  35. int n;
  36. scanf("%d",&n);//结点个数
  37. pre.resize(n+1),post.resize(n+1);
  38. for(int i=1;i<=n;i++)
  39. scanf("%d",&pre[i]);
  40. for(int i=1;i<=n;i++)
  41. scanf("%d",&post[i]);
  42. puts(getIn(1,n,1,n)?"Yes":"No");
  43. //for(int i=1;i<=in.size();i++)
  44. for(int i = 1; i <= len; i++)
  45. printf("%d%c",in[i],i==len?'\n':' ');
  46. system("pause");
  47. return 0;
  48. }

法3


  
  1. #include<iostream>
  2. #include<stdio.h>
  3. #include<stdlib.h>
  4. #include<math.h>
  5. #include<string.h>
  6. #include<algorithm>
  7. #include<map>
  8. #include<vector>
  9. #include<queue>
  10. using namespace std;
  11. //树不唯一:一个结点只有左子树或者右子树
  12. //查找得到的先根序列中根节点的下一结点在后根序列中的位置正好等于right-1
  13. int N,pre[30],post[30];
  14. vector<int>in;
  15. bool flag=true;//表示树的形态唯不唯一
  16. void inOrder(int root,int left,int right){//得到中序序列
  17. if(left>=right){
  18. if(left==right)//如果只有一个结点
  19. in.push_back(pre[root]);
  20. return;//直接返回
  21. }
  22. int i=left;
  23. while(i<=right-1&&post[i]!=pre[root+1])
  24. //查找先序序列中根结点的下一结点在后序序列中的位置
  25. i++;
  26. if(i==right-1)
  27. //先序序列中根结点的下一结点在后序序列中的位置正好等于right-1
  28. flag=false;//树的形态不唯一
  29. inOrder(root+1,left,i);//递归遍历左子树
  30. in.push_back(pre[root]);//将根结点压入中序序列
  31. inOrder(root+i-left+2,i+1,right-1);
  32. }
  33. int main(){
  34. scanf("%d",&N);
  35. for(int i=0;i<N;i++)
  36. scanf("%d",&pre[i]);
  37. for(int i=0;i<N;i++)
  38. scanf("%d",&post[i]);
  39. inOrder(0,0,N-1);
  40. printf("%s\n",flag==true?"Yes":"No");
  41. for(int i=0;i<in.size();i++)
  42. printf("%s%d",i>0?" ":"",in[i]);
  43. printf("\n");
  44. system("pause");
  45. return 0;
  46. }

 

文章来源: andyguo.blog.csdn.net,作者:山顶夕景,版权归原作者所有,如需转载,请联系作者。

原文链接:andyguo.blog.csdn.net/article/details/104030565

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。