1. 程式人生 > >資料結構——根據兩種遍歷方式推得另外一種遍歷方式

資料結構——根據兩種遍歷方式推得另外一種遍歷方式

首先說一下,只有 先序+中序——>後序,以及後序+中序——>前序,這兩種推舉方式,因為當只給出前序以及後序的遍歷方式時,推得的中序是不唯一的,也就是不存在。

方法(核心):是根據每種遍歷方式的特點,以前序遍歷和後序遍歷為基準,對中序遍歷進行割裂(這裡姑且稱它為割裂法)。

這個要求我們對三種遍歷方式 爛熟於心(必須透徹瞭解!!!)才能推得建樹方式。這裡給出兩篇講的很不錯的部落格 三種遍歷方式詳解知二推三的粗略程式碼

由於先序遍歷的便捷性,中序遍歷前序遍歷推得後續遍歷是比較容易的,所以這裡只給出中+後——>前的程式碼。

一定要牢記上面所說的割裂方法,瞭解此方法後,這些程式碼是不必要記住的。

 

下面的程式碼同時對應了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;
}