已知前序中序求后續;已知中序后序求前序;


后序遍歷與中序遍歷,求前序遍歷

首先,一點基本常識,給你一個后序遍歷,那么最后一個就是根(同理前序遍歷,第一個是根)

那么這個算法的核心就是不斷的求根;

接下來我用一個實例來說明怎樣進行求根:

 

 

 例如以上,給出后序遍歷和中序遍歷,求前序遍歷

首先根據后序遍歷的最后一個就是根,可以知道4是根,以此可將前序和后序都分為三部分;

 

看上圖,在前序遍歷中,綠色框中的4為根,則在4的左邊,紅色框的就為以4為根的左子樹,黃色框的就是以4為根的右子樹。

則在找到4這個根之后,此題可以轉換為兩個子問題,一下:

求紅框的前序列,求黃框的前序列。

之后就可以遞歸了;我們再回到上面的圖,再進行一個小小的思考;

觀察前序遍歷和后序遍歷,都可以由三部分組成,紅框的左子樹,黃框的右子樹以及綠框的根;

那么,在進行函數遞歸的時候,重點就是怎樣計算各個部分的下標起始,來讓程序可以遞歸下去;

上代碼:

方法一:

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
void beford(string in,string after){
    if (in.size()>0){
        char ch=after[after.size()-1];
        cout<<ch;//找根輸出
        int k=in.find(ch);
        beford(in.substr(0,k),after.substr(0,k));
        beford(in.substr(k+1),after.substr(k,in.size()-k-1));//遞歸左右子樹;
    }
}
int main(){
    string inord,aftord;
    cin>>inord;cin>>aftord;//讀入
    beford(inord,aftord);cout<<endl;
    return 0;
}

上面代碼的關鍵是,用substr函數將字符串進行切割,以此來達到分離字符串三部分的操作比較好理解。

方法二:

#include<iostream>
using namespace std;
int a[35],b[35];
void build(int l1,int r1,int l2,int r2)
{
    if(l1>r1) return;
    cout<<" "<<b[r2];
    int p = l1;
    while(a[p]!=b[r2])
    {
        p++;
    }
    int cnt = p - l1;
    build(l1,p-1,l2,l2+cnt-1);
    build(p+1,r1,l2+cnt,r2-1);
}
int main()
{
    int n;
    cin>>n;
    for(int i=0;i<n;i++)
    {
        cin>>b[i];
    }
    for(int i=0;i<n;i++)
    {
        cin>>a[i];
    }
    build(0,n-1,0,n-1);
} 

和上面的方法核心思想是不變的,但是有一點差別是,傳入函數的不再是序列整體,而是用左右下標的方式來進行遞歸;

特別注意,函數中的 cnt = p-l1, cnt是左子樹的長度,及黃框的長度,以此來進行遞歸;

已知前序和中序求后序的操作和以上一樣,只是將遞歸和查詢的位置變化,並且由於后序遍歷根是在最后才輸出,因此輸出的代碼應該放到搜索代碼的后面;

附上已知前序中序求后序的代碼:

#include<bits/stdc++.h>
using namespace std;
char a[500];
char b[500];
int n;
void dfs(int l1,int r1,int l2,int r2)
{
    if(l1>r1||l2>r2) return ;
    char x =a[l1];
    int p=l2;
    while(b[p]!=x)
    {
        p++;    
    }
    int ent = p-l2;
    dfs(l1+1,l1+ent,l2,p-1);
    dfs(l1+ent+1,r1,p+1,r2);
    cout<<x;// 特別注意輸出代碼的位置!
}
int main()
{
    scanf("%d",&n);
    scanf("%s",&a);
    scanf("%s",&b);    
    dfs(0,n-1,0,n-1);
}

 

以上。可能講的有點恍惚,有不懂的請評論留言;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM