pat甲级--根据中左,中后序遍历输出

这篇博客主要探讨了二叉树的中左视图、最低公共祖先以及前序和后序遍历的问题,包括相关算法和实现细节。
摘要由CSDN通过智能技术生成

7-3 Left-View of Binary Tree (25 分)

#include<iostream>
#include<cstdlib>
#include<vector>
#include<queue>
#include<set>
using namespace std;
const int maxn = 20;
int in[maxn],pre[maxn];
int n;
struct node{
	int data;
	node* lchild;
	node* rchild;
	int level;
};

node* createTree(int preL,int preR,int inL,int inR)
{
	if(preL>preR)
        return NULL;
	node* root=(node*)malloc(sizeof(struct node));
	root->data = pre[preL];
	int i;
	for(i=inL; i<=inR; i++)
	{
		if(in[i]==pre[preL])
            break;
	}
	int k=i-inL;

	root->lchild=createTree(preL+1,preL+k,inL,i-1);
	root->rchild=createTree(preL+k+1,preR,i+1,inR);
	return root;
}

vector<int> ans;

void level(node* root)          //层序遍历法
{
	set<int> s;
	queue<node*> q;             //设置一个节点类型的队列
	root->level = 1;                    //标记初始的层为1
	
	q.push(root);
	node* tmp;
	while(!q.empty())
    {
		tmp = q.front();
		q.pop();
		if(s.count(tmp->level)==0)
		{
			s.insert(tmp->level);
			ans.push_back(tmp->data);
		}
		if(tmp->lchild)
		{
			tmp->lchild->level = tmp->level+1;
			q.push(tmp->lchild);
		}
		if(tmp->rchild)
		{
			tmp->rchild->level = tmp->level+1;
			q.push(tmp->rchild);
		}
	}
}

int main()
{
	scanf("%d",&n);         //读入n

	for(int i=0; i<n; i++)
    {
		scanf("%d",&in[i]);             //读入中序遍历的结果
	}

	for(int i=0; i<n; i++)
    {
		scanf("%d",&pre[i]);            //读入前序遍历的结果
	}

	node* root = createTree(0,n-1,0,n-1);           //建树

	level(root);
	
	for(int i=0; i<ans.size(); i++)
    {
        if(i!=0)
            cout << " ";
        cout << ans[i];
	}
}

7-4 LCA in a Binary Tree (30 分)

#include <iostream>
#include <cstring>
#include <algorithm>
#include <unordered_map>

using namespace std;

const int N = 10010;

int m, n;
int in[N], pre[N], seq[N];
unordered_map<int, int> pos;
int p[N], depth[N];

int build(int il, int ir, int pl, int pr, int d)
{
    int root = pre[pl];
    int k = root;

    depth[root] = d;

    if (il < k) p[build(il, k - 1, pl + 1, pl + 1 + (k - 1 - il), d + 1)] = root;
    if (k < ir) p[build(k + 1, ir, pl + 1 + (k - 1 - il) + 1, pr, d + 1)] = root;

    return root;
}

int main()
{
    cin >> m >> n;

    for (int i = 0; i < n; i ++ )
    {
        cin >> seq[i];                  //seq就是前序遍历
        pos[seq[i]] = i;            //pos就是映射
        in[i] = i;
    }

    for (int i = 0; i < n; i ++ )
    {
        cin >> pre[i];               //先输入前序
        pre[i] = pos[pre[i]];          //反过来映射
    }

    build(0, n - 1, 0, n - 1, 0);

    while (m -- )
    {
        int a, b;
        cin >> a >> b;
        if (pos.count(a) && pos.count(b))
        {
            a = pos[a], b = pos[b];
            int x = a, y = b;
            while (a != b)
                if (depth[a] > depth[b]) a = p[a];
                else b = p[b];

            if (a != x && a != y) printf("LCA of %d and %d is %d.\n", seq[x], seq[y], seq[a]);
            else if (a == x) printf("%d is an ancestor of %d.\n", seq[x], seq[y]);
            else printf("%d is an ancestor of %d.\n", seq[y], seq[x]);
        }
        else if (pos.count(a) == 0 && pos.count(b) == 0)
            printf("ERROR: %d and %d are not found.\n", a, b);
        else if (pos.count(a) == 0)
            printf("ERROR: %d is not found.\n", a);
        else
            printf("ERROR: %d is not found.\n", b);
    }

    return 0;
}


D Lowest Common Ancestor (30 分)


#include<iostream>
#include<unordered_map>
#include<algorithm>
using namespace std;

const int maxn=10010;

int n,m;

int seq[maxn],in[maxn],pre[maxn],p[maxn];

int depth[maxn];

unordered_map<int,int> pos;

int build(int il,int ir,int prel,int prer,int d)
{
    int root=pre[prel];
    int k=root;

    depth[root]=d;

    if(il<k)
        p[build(il,k-1,prel+1,prel+k-il,d+1)]=root;

    if(k<ir)
        p[build(k+1,ir,prel+1+k-il,prer,d+1)]=root;

    return root;
}

int main()
{
    cin >> m >> n;

    for(int i=0; i<n; i++)
    {
        cin >> seq[i];
        pre[i]=seq[i];
    }

    sort(seq,seq+n);

    for(int i=0; i<n; i++)
    {
        pos[seq[i]]=i;
        in[i]=i;
    }
    for(int i=0; i<n; i++)
        pre[i]=pos[pre[i]];


    build(0,n-1,0,n-1,0);

    while(m--)
    {
        int a,b;
        cin >> a >> b;
        if(pos.count(a)!=0 && pos.count(b)!=0)
        {
            a=pos[a],b=pos[b];
            int x=a,y=b;
            while(a!=b)
                if(depth[a]>depth[b])
                    a=p[a];
                else
                    b=p[b];

            if(a!=x && a!=y)
                printf("LCA of %d and %d is %d.\n",seq[x],seq[y],seq[a]);
            else if(a==x)
                printf("%d is an ancestor of %d.\n",seq[x],seq[y]);
            else
                 printf("%d is an ancestor of %d.\n",seq[y],seq[x]);

        }
        else if(pos.count(a)==0 && pos.count(b)==0)
            printf("ERROR: %d and %d are not found.\n",a,b);
        else if(pos.count(a)==0)
            printf("ERROR: %d is not found.\n",a);
        else
            printf("ERROR: %d is not found.\n",b);
    }

}

C Postorder Traversal (25 分)


#include<iostream>
#include<unordered_map>
using namespace std;

const int maxn=50010;

int n;

int pre[maxn],in[maxn];

unordered_map<int,int> pos;

int post;

void build(int il,int ir,int prel,int prer)
{
    int root=pre[prel];
    int k=pos[root];

    if(il<k)
        build(il,k-1,prel+1,prel+k-il);

    if(k<ir)
        build(k+1,ir,prel+1+k-il,prer);

    if(!post)
        post=root;

}

int main()
{
    cin >> n;
    for(int i=0; i<n; i++)
        cin >> pre[i];

    for(int i=0; i<n; i++)
    {
        cin >> in[i];
        pos[in[i]]=i;
    }

    build(0,n-1,0,n-1);

    cout << post;

    return 0;

}

ZigZagging on a Tree


#include<iostream>
#include<unordered_map>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;

const int maxn=33;

int n;

int postorder[maxn],inorder[maxn];

unordered_map<int,int> pos,l,r;

vector<int> res;

int build(int inl,int inr,int postl,int postr)
{
    int root=postorder[postr];
    int k=pos[root];

    if(inl<k)
        l[root]=build(inl,k-1,postl,postl+k-inl-1);

    if(k<inr)
        r[root]=build(k+1,inr,postl+k-inl,postr-1);

    return root;
}

void bfs(int u)
{
    queue<int> q;
    q.push(u);
    bool flag=true;
    while(q.size())
    {
        int size=q.size();
        for(int i=0; i<size; i++)
        {
            int t=q.front();
            q.pop();
            res.push_back(t);
            if(l[t])
                q.push(l[t]);
            if(r[t])
                q.push(r[t]);
        }
        if(flag)
            reverse(res.end()-size,res.end());
        flag=!flag;
    }
}

int main()
{
    cin >> n;
    for(int i=0; i<n; i++)
    {
        cin >> inorder[i];
        pos[inorder[i]]=i;
        inorder[i]=i;
    }
    for(int i=0; i<n; i++)
        cin >> postorder[i];

    int root=build(0,n-1,0,n-1);

    bfs(root);

    for(int i=0; i<res.size(); i++)
    {
        if(i)
            cout << " ";
        cout << res[i];
    }
    return 0;
}

Pre- and Post-order Traversals


#include<iostream>
using namespace std;

const int maxn=33;

int n;

int pre[maxn],post[maxn];


int dfs(int l1,int r1,int l2,int r2,string &s)
{
    if(l1>r1)
        return 1;
    if(pre[l1]!=post[r2])
        return 0;

    int cnt=0;
    for(int i=l1; i<=r1; i++)
    {
        string lin,rin;
        int lcnt=dfs(l1+1,i,l2,l2+i-l1-1,lin);
        int rcnt=dfs(i+1,r1,l2+i-l1,r2-1,rin);

        if(lcnt && rcnt)
        {
            cnt+=lcnt*rcnt;
            s=lin+to_string(pre[l1])+" "+rin;
            if(cnt>1)
                break;
        }

    }
    return cnt;
}

int main()
{
    cin >> n;
    for(int i=0; i<n; i++)
        cin >> pre[i];
    for(int i=0; i<n; i++)
        cin >> post[i];

    string in;
    int cnt=dfs(0,n-1,0,n-1,in);

    if(cnt>1)
        cout << "No" << endl;
    else
        cout << "Yes" << endl;

    in.pop_back();
    cout << in << endl;

    return 0;

}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值