二叉树:给后序中序遍历,求前序

给出后序中序, 求前序:

1、给后序中序求前序,因为后序序列左右根从后往前是根右左的顺序。因此递归先造右子树,再造左子树。
2、给前序中序求后序,因为前序序列是根左右,从前往后是根左右。因此递归先造左子树再造右子树。
题目:P1030 [NOIP2001 普及组] 求先序排列
字符串版本:
题解:

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

const int N = 10010;

int pos, n;
string in_s, post_s;
int pre[N], in[N], post[N];
struct node
{
	int l, r;
    char w;
}T[N];

// 建树
void creat(int inl, int inr, int u)
{
    // 如果是空子树 返回上一层
	if(inl > inr) return ;

    // 赋予当前节点值等于后序序列的右边往左数的数,左右孩子的位置
	T[u].w = post_s[pos--];
	T[u].l = 2 * u, T[u].r = 2 * u + 1;

    //找到中序遍历序列的root节点, 
	int mid;
	for(mid = inl; mid <= inr; mid++)
		if(T[u].w == in_s[mid]) break;
	// 递归创建子树. 如果是给后序序列,先遍历右边,如果是给前序序列,先遍历左边。
	creat(mid + 1, inr, 2 * u + 1); //必须先递归右子树,因为后续遍历的根节点前面一些点一定是右子树的点,而我们是根据后续遍历的根节逐渐前移来去找递归的
	creat(inl, mid - 1, 2 * u);
}

// 进行层序遍历
void bfs()
{
	int idx = 0;
	queue<int> q;
	q.push(1);
	while(q.size())
	{
		node t = T[q.front()];
		q.pop();
		if(!idx) cout << t.w;
		else cout << " " << t.w;
		idx++;
		
		if(t.l > 0 && t.l <= n) q.push(t.l);
		if(t.r > 0 && t.r <= n) q.push(t.r);
	}
}

void preout(int u)
{
    if(T[u].w == -1) return ;
    cout<<T[u].w;
    preout(u * 2 );
    preout(u * 2 + 1);
}
int main()
{


	cin >> in_s >> post_s;
    n = in_s.size();
    pos = n;

    in_s = " "+ in_s;
    post_s = " " + post_s;
   
    
	
	memset(T, -1, sizeof T);
	
    // for(int i =0 ; i < n ; i ++)
    // {
    //     cout<<T[i].l<<" "<<T[i].r<<" "<<T[i].w<<endl;
    // }


	creat(1, n, 1);
	// bfs();
    
	// cout << endl;

    // cout<<"----"<<endl;
    preout(1);
	
	return 0;
}

数字版本:

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

const int N = 10010;

int pos, n;
int pre[N], in[N], post[N];
struct node
{
	int l, r, w;
}T[N];

// 建树
void creat(int inl, int inr, int u)
{
	if(inl > inr) return ;
	
	T[u].w = post[pos--];
	T[u].l = 2 * u, T[u].r = 2 * u + 1;
	int mid;
	for(mid = inl; mid <= inr; mid++)
		if(T[u].w == in[mid]) break;
	
	creat(mid + 1, inr, 2 * u + 1); //必须先递归右子树,因为后续遍历的根节点前面一些点一定是右子树的点,而我们是根据后续遍历的根节逐渐前移来去找递归的
	creat(inl, mid - 1, 2 * u);
}

// 进行层序遍历
void bfs()
{
	int idx = 0;
	queue<int> q;
	q.push(1);
	while(q.size())
	{
		node t = T[q.front()];
		q.pop();
		if(!idx) cout << t.w;
		else cout << " " << t.w;
		idx++;
		
		if(T[t.l].w != -1) q.push(t.l);
		if(T[t.r].w != -1) q.push(t.r);
	}
}

int f = 1;
void preout(int u)
{
    if(T[u].w == -1) return ;
    if(f == 1) cout<<T[u].w;
    else 
        cout<<" "<<T[u].w;
    f ++;
    preout(u * 2 );
    preout(u * 2 + 1);
}
int main()
{
	cin >> n;
    pos = n;

	for(int i = 1; i <= n ; i ++) cin >> post[i];
	for(int i = 1; i <= n ; i ++) cin >> in[i];
	
	memset(T, -1, sizeof T);
	
	creat(1, n, 1);
	// bfs();
    preout(1);
	cout << endl;
	
	return 0;
}

给后序中序求前序

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

const int N = 1e4+10;

int pre[N], in[N], post[N];

typedef struct node{
    int v, l, r;
}node;

node T[N];
int n, n1 = 1;

void buildTree(int inl, int inr, int u)
{
    if(inl > inr) return ;

    T[u].v = pre[n1 ++];
    T[u].l = u * 2;
    T[u].r = u * 2 + 1;

    int mid;
    for(mid = inl; mid <= inr; mid ++)
        if(in[mid] == T[u].v) break;
    buildTree(inl, mid - 1, T[u].l);
    buildTree(mid + 1, inr, T[u].r);
}

void printPost(int u)
{
    if(T[u].v == -1) return ;

    printPost(T[u].l);
    printPost(T[u].r);
    cout<<T[u].v<<" ";
}

int main()
{
    cin >> n;
    // n1 = n;
    for(int i = 1; i <= n ; i ++) cin >> pre[i];
    for(int i = 1; i <= n ; i ++) cin >> in[i];

    memset(T, -1, sizeof T);

    buildTree(1, n, 1);
    printPost(1);
    return 0;
}```

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值