PAT A1020 Tree Traversals

PAT A1020 Tree Traversals

在这里插入图片描述

Sample Input:

7
2 3 1 5 7 6 4
1 2 3 4 5 6 7

Sample Output:

4 1 6 3 5 7 2
  • 思路1:
    先用后序序列(postorder)和中序序列(inorder)建立起二叉树,再用BFS(一个queue)将层序遍历序列输出

  • code1:

#include <queue>
#include <cstring>
#include <algorithm>
#include <stdio.h>
using namespace std;
const int maxn = 100;
int n, post[maxn], in[maxn];

struct node{
	int data;
	node* lc;
	node* rc;
};

node* create(int postL, int postR, int inL, int inR){
	if(postL >= postR) return NULL;
	node* root = new node;
	root->data = post[postR-1];
	root->lc = NULL;
	root->rc = NULL;
	int i;
	for(i = inL; i < inR; ++i){
		if(in[i] == post[postR-1])
			break;
	}
	int num = i - inL;
	//Q:为什么必须用num?直接i出错 
	root->lc = create(postL, postL+num, inL, i);
	root->rc = create(postL+num, postR-1, i+1, inR);
	return root;
}

int num = 0;	//已经输出节点个数

void BFS(node* root){
	queue<node*> q;
	q.push(root);
	while(!q.empty()){
		node* now = new node;
		now = q.front();
		q.pop();
		printf(now->data);
		num++;
		if(num < n)
		printf(" ");
		if(now->lc != NULL) q.push(now->lc);
		if(now->rc != NULL) q.push(now->rc);
	}
} 

int main(){
	scanf("%d", &n);
	for(int i = 0; i < n; ++i){
		scanf("%d", post+i);
	}	
	for(int i = 0; i < n; ++i){
		scanf("%d", in+i);
	}
	node* root = create(0, n, 0, n);
	BFS(root);
	return 0;
}
  • 上面是按[L, R)来建立二叉树,如果中序后序区间改为[L, R]的话,改动如下
node* create(int postL, int postR, int inL, int inR){
	if(postL > postR) return NULL;
	...
	for(i = inL; i <= inR; ++i)
	...
	root->lc = create(postL, postL+num-1, inL, i+1);
	root->rc = create(postL+num, postR-1, i+1, inR);
	return root;
}
int main(){
	....
	node* root = create(0, n-1, 0, n-1);
	...
}
  • 思路 2:静态树存储,建树+BFS

  • T2 code:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 110;
int post[maxn], in[maxn], idex = 0;
struct Node{
	int data, lc, rc;
	Node(){
		lc = rc = -1;
	}
}node[maxn];

int NewNode(int x){
	node[idex].data = x;
	node[idex].lc = -1;
	node[idex].rc = -1;
	return idex++;
}

int Create(int postL, int postR, int inL, int inR){
	if(postL > postR){
		return -1;
	}
	int r = NewNode(post[postR]);
//	cout << post[postR] <<endl;
	int id = inL;
	while(id <= inR && in[id] != post[postR]) id++;
	int numL = id - inL;
	node[r].lc = Create(postL, postL + numL -1, inL, id - 1);
	node[r].rc = Create(postL + numL, postR - 1, id + 1, inR); 	
	return r;
}
	
int n, cnt = 0;
void BFS(int r){
	queue<int> q;
	q.push(r);
	while(!q.empty()){
		int now = q.front();
		printf("%d", node[now].data);
		if(++cnt < n) printf(" "); 
		q.pop();
		if(node[now].lc != -1) q.push(node[now].lc);
		if(node[now].rc != -1) q.push(node[now].rc);
	}
}

int main(){
	scanf("%d", &n);
	for(int i = 0; i < n; ++i){
		scanf("%d", &post[i]);
	}
	for(int i = 0; i < n; ++i){
		scanf("%d", &in[i]);
	}
	int r = Create(0, n-1, 0, n-1);
	BFS(r);
	return 0;
} 
  • 思路3: 不建树,Create()中加一个layer参数,将树按layer输入二维数组中,再按层遍历二维数组

  • T2 code:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 110;
int post[maxn], in[maxn];
int n,  max_layer = 0;
vector<int> n_layer[maxn];
void Create(int layer, int postL, int postR, int inL, int inR){
	if(postL > postR){
		max_layer = max(max_layer, layer);
		return;
	}
	int r = post[postR];
	n_layer[layer].push_back(r);
	int id = inL;
	while(id <= inR && in[id] != post[postR]) id++;
	int numL = id - inL;
	Create(layer + 1, postL, postL + numL -1, inL, id - 1);
	Create(layer + 1, postL + numL, postR - 1, id + 1, inR);
}

int main(){
	scanf("%d", &n);
	for(int i = 0; i < n; ++i){
		scanf("%d", &post[i]);
	}
	for(int i = 0; i < n; ++i){
		scanf("%d", &in[i]);
	}
	Create(0, 0, n-1, 0, n-1);
	int cnt = 0;
	for(int i = 0; i < max_layer; ++i){
		for(int j = 0; j < n_layer[i].size(); ++j){
			printf("%d", n_layer[i][j]);
			if(++cnt < n) printf(" ");
		}
	}
//	BFS(root);
	return 0;
}

  • T3 code: 不建树,数组存储法(改成set或priority_queue实现) 直接输出
    set版本:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 50;
vector<int> post, in;
struct Node
{
    int data, id;
    bool operator < (const Node & tmp) const
    {
        return id < tmp.id;
    }
};
set<Node> ans;

void Create(int postL, int postR, int inL, int inR, int id)
{
    if(postL >= postR) return;
    int r = post[postR-1], tid = inL;
    ans.insert(Node{r, id});
    while(tid < inR && in[tid] != r) tid++;
    int numL = tid - inL;
    Create(postL, postL+numL, inL, tid, 2*id);
    Create(postL+numL, postR-1, tid+1, inR, 2*id+1);
}
int main()
{
    int n;
    scanf("%d", &n);
    post.resize(n); in.resize(n);
    for(int i = 0; i < n; ++i)
    {
        scanf("%d", &post[i]);
    }
    for(int i = 0; i < n; ++i)
    {
        scanf("%d", &in[i]);
    }
    Create(0, n, 0, n, 1);
    for(auto it = ans.begin(); it != ans.end(); ++it)
    {
        if(it == ans.begin()) printf("%d", (*it).data);
        else printf(" %d", (*it).data);
    }
    return 0;
}

priority_queue版本:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 50;
vector<int> post, in;
struct Node
{
    int data, id;
    bool operator < (const Node & tmp) const
    {
        return id > tmp.id;
    }
};
priority_queue<Node> ans;

void Create(int postL, int postR, int inL, int inR, int id)
{
    if(postL >= postR) return;
    int r = post[postR-1], tid = inL;
    ans.push(Node{r, id});
    while(tid < inR && in[tid] != r) tid++;
    int numL = tid - inL;
    Create(postL, postL+numL, inL, tid, 2*id);
    Create(postL+numL, postR-1, tid+1, inR, 2*id+1);
}
int main()
{
    int n;
    scanf("%d", &n);
    post.resize(n); in.resize(n);
    for(int i = 0; i < n; ++i)
    {
        scanf("%d", &post[i]);
    }
    for(int i = 0; i < n; ++i)
    {
        scanf("%d", &in[i]);
    }
    Create(0, n, 0, n, 1);
    int cnt = 0;
    while(!ans.empty())
    {
        printf("%d", ans.top());
        ans.pop();
        if(++cnt < n) printf(" ");
    }
    return 0;
}

  • T5:
#include <bits/stdc++.h>
using namespace std;
vector<int> post, in;
unordered_map<int, int> pos_in;

typedef pair<int, int> pr;  // <id, val>
priority_queue<pr, vector<pr>, greater<pr> > pq;
void Create(int postL, int postR, int inL, int inR, int id){
    //在[postL, postR)建树
    if(postL >= postR) return;
    int r = post[postR-1], tid = pos_in[r], numL = tid - inL;
    pq.push(make_pair(id, r));
    Create(postL, postL+numL, inL, tid, 2*id);
    Create(postL+numL, postR-1, tid+1, inR, 2*id+1);
}

int main(){
    int n;
    scanf("%d", &n);
    post.resize(n);
    in.resize(n);
    for(int i = 0; i < n; ++i) scanf("%d", &post[i]);
    for(int i = 0; i < n; ++i){
        scanf("%d", &in[i]);
        pos_in[in[i]] = i;
    }
    Create(0, n, 0, n, 1);
    while(!pq.empty()){
        printf("%d", pq.top().second);
        pq.pop();
        if(!pq.empty()) printf(" ");
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值