1020. Tree Traversals (25)

Posted lan126

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了1020. Tree Traversals (25)相关的知识,希望对你有一定的参考价值。

距离18号的PAT考试还有18天,最重要的是挖透做过的每一题

 

(1)基本思路:

1.建树用right数组和left保存各个节点的右左节点

2.层次遍历

 

#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;

#define M 32
int post[M];
int in[M];
int n;
int left[M];
int right[M];
queue<int> q;

//建树
int built_tree(int st1,int end1,int st2,int end2,int root){
  if(st1 > end1 || st2 > end2) return 0;
  if(st1 == end1 || st2 == end2) return post[st1];
  for(int i=st2;i<=end2;i++) {
    if(root == in[i]) {
      int ne1=st1+i-st2-1;
      left[root]=built_tree(st1,ne1,st2,i-1,post[ne1]);
      right[root]=built_tree(ne1+1,end1-1,i+1,end2,post[end1-1]);
    }
  }
  return root;
}

int main() {
  scanf("%d",&n);
  
  memset(post,0,sizeof(post));
  memset(in,0,sizeof(in));
  memset(left,0,sizeof(left));
  memset(right,0,sizeof(right));

  for(int i=0;i<n;i++) {
    int node;
    scanf("%d",&node);
    post[i]=node;
  }
  for(int i=0;i<n;i++) {
    int node;
    scanf("%d",&node);
    in[i]=node;
  }

  int root=built_tree(0,n-1,0,n-1,post[n-1]);  
  /*
  printf("L:");
  for(int i=1;i<=n;i++) {
    printf("%d ",left[i]);
  }
  printf("\\nR:");
  for(int i=1;i<=n;i++) {
    printf("%d ",right[i]);
  }
  printf("\\n");
  */
//层次遍历
  q.push(root);
  int cnt=0;
  while(!q.empty()) {
    int index=q.front();
    cnt==0? printf("%d",index):printf(" %d",index); 
    q.pop();
    cnt++;
    if(left[index] != 0) {
      q.push(left[index]);
    }
    if(right[index]!=0) {
      q.push(right[index]);
    }
  }
  return 0;
}

 

(2)不建树直接用一个数组存储结果

 

不过在这之前先试一下更简单的---转换成先序(根左右)

#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;

#define M 32
int post[M];
int in[M];
int n;

//start 为in中的start end同,root为post中的root
void pre(int root,int start,int end,int cnt) {
  if(start > end) return;
  //find left subtree and right subtree
  //比如左子树不存在那么该算法会认为根为左子树的start而end则是通过根减一得到
  //所以会产生start比end大的情况
  //同理右子树不存在start为i+1而新的end为原来的end

  //如果是一个节点的树那么会有start=end
  //如果start end相等就是多个节点的树
  int i;
  for(i=start;i<=end;i++) {
    if(in[i]==post[root]) break;
  }
  cnt == 0? printf("%d",post[root]):printf(" %d",post[root]);
  //left subtree
  pre(root-end+i-1,start,i-1,++cnt);
  //right subtree
  pre(root-1,i+1,end,++cnt);
}

int main() {
  scanf("%d",&n);
  
  memset(post,0,sizeof(post));
  memset(in,0,sizeof(in));
  for(int i=0;i<n;i++) {
    int node;
    scanf("%d",&node);
    post[i]=node;
  }
  for(int i=0;i<n;i++) {
    int node;
    scanf("%d",&node);
    in[i]=node;
  }
  
  pre(n-1,0,n-1,0);
  return 0;
}

 

层次遍历

技巧就是虽然不是层次遍历但是可以用index来得到对应的层次中的节点

                           1

                   |                 |

                  2                  3

            |          |         |          |

         4            5        6         7

      访问顺序虽然是1 2 4  5  3 6 7 (先序)

  但是用index从零开始记录

  访问顺序虽然没有变但是存在数组的位置却是按照层次来的 比如0位置存1    2*0+1位置 存2  2*0+2存3以后同理

#include <cstdio>
#include <cstring>
using namespace std;

#define M 32
//数组开大一点不然最后一个过不去
#define N 1000000
int post[M];
int in[M];
//不能只开M的大小的数组因为空节点也会存在level中
int level[N];
int n;

void pre(int root,int start,int end,int index) {
  if(start > end) return;
  int i;
  for(i=start;i<=end;i++) {
    if(in[i]==post[root]) break;
  }
level[index]=post[root]; //left subtree pre(root-end+i-1,start,i-1,2*index+1); //right subtree pre(root-1,i+1,end,2*index+2); } int main() { scanf("%d",&n); memset(post,0,sizeof(post)); memset(in,0,sizeof(in)); memset(level,-1,sizeof(level)); for(int i=0;i<n;i++) scanf("%d",&post[i]); for(int i=0;i<n;i++) scanf("%d",&in[i]); pre(n-1,0,n-1,0); // 由于可能存在空节点即为-1的点所以要跳过 int cnt=0; for(int i=0;i<N;i++) { //n个节点全部打印出 if(cnt == n) break; if(level[i] == -1) continue; cnt==0? printf("%d",level[i]):printf(" %d",level[i]); cnt++; } return 0; }

 

 

以上是关于1020. Tree Traversals (25)的主要内容,如果未能解决你的问题,请参考以下文章

PAT 1020 Tree Traversals (25)

1020 Tree Traversals (25 分)

1020 Tree Traversals (25分)

1020 Tree Traversals (25 分)

1020. Tree Traversals (25)

PAT Advanced 1020 Tree Traversals (25分)