数据结构——根据两种遍历方式推得另外一种遍历方式

版权声明:转载请注明 https://blog.csdn.net/NCC__dapeng/article/details/83830491

首先说一下,只有 先序+中序——>后序,以及后序+中序——>前序,这两种推举方式,因为当只给出前序以及后序的遍历方式时,推得的中序是不唯一的,也就是不存在。

方法(核心):是根据每种遍历方式的特点,以前序遍历和后序遍历为基准,对中序遍历进行割裂(这里姑且称它为割裂法)。

这个要求我们对三种遍历方式 烂熟于心(必须透彻了解!!!)才能推得建树方式。这里给出两篇讲的很不错的博客 三种遍历方式详解知二推三的粗略代码

由于先序遍历的便捷性,中序遍历前序遍历推得后续遍历是比较容易的,所以这里只给出中+后——>前的代码。

一定要牢记上面所说的割裂方法,了解此方法后,这些代码是不必要记住的。

下面的代码同时对应了PTA的一道题目,这里给出题目以及AC代码;

7-1 根据后序和中序遍历输出先序遍历 (25 分)

本题要求根据给定的一棵二叉树的后序遍历和中序遍历结果,输出该树的先序遍历结果。

输入格式:

第一行给出正整数N(≤30),是树中结点的个数。随后两行,每行给出N个整数,分别对应后序遍历和中序遍历结果,数字间以空格分隔。题目保证输入正确对应一棵二叉树。

输出格式:

在一行中输出Preorder:以及该树的先序遍历结果。数字间有1个空格,行末不得有多余空格。

输入样例:

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

输出样例:

Preorder: 4 1 3 2 6 5 7

AC代码(割裂法): 

#include <bits/stdc++.h>

using namespace std;
const int maxn=1e5+10;

int last[maxn],mid[maxn];

typedef struct node
{
    int data;
    node* left;
    node* right;
}*BiTree;


node* solve(int *last,int *mid,int len)
{

    if(len==0) return NULL;

    int pos=0;
    for(int i=0;i<len;i++)
    {
        if(mid[i]==last[len-1])
        {
            pos=i;
            break;
        }
    }

    
    BiTree nodes=new node();
    nodes->data=mid[pos];
    //构建左子树
    nodes->left=solve(last,mid,pos);
    //构建右子树
    nodes->right=solve(last+pos,mid+pos+1,len-pos-1);

    return nodes;
}

void Preorder(BiTree tree)//先序遍历
{
    if(tree==NULL) return;
    printf(" %d",tree->data);
    Preorder(tree->left);
    Preorder(tree->right);
}

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


    BiTree tree=solve(last,mid,n);

    cout<<"Preorder:";
    Preorder(tree);

    return 0;
}

猜你喜欢

转载自blog.csdn.net/NCC__dapeng/article/details/83830491