樹遍歷的應用——樹的重建

樹遍歷的應用——樹的重建

問題描述:現有兩個結點序列,分別是對同一個二叉樹進行前序遍歷和中序遍歷。請輸出該二叉樹的後序遍歷。

 

輸入:第一行輸入二叉樹的結點數。

           第二行輸入前序遍歷的結點編號序列,相鄰編號用空格隔開。

           第三行輸入中序遍歷的結點編號序列,相鄰編號用空格隔開。

輸出:在一行輸出按後序遍歷時的結點編號序列。相鄰結點用1個空格隔開。

限制:1 < 結點數< 100

 

樣例輸入:3

                     1 2 3

                     2 1 3

樣例輸出:2 3 1

                    

 

分析:前序遍歷序列pre中依次爲根結點的編號,例如,pre[] = {1, 2, 3, 4, 5, 7, 8}

在中序遍歷序列in中, in[] = {3, 2, 5, 4, 6, 1, 8, 7},從而序列in中根結點1左邊的序列

3, 2, 5, 4, 6爲根結點1的左子樹,根結點右邊的序列8,7爲右子樹。

這樣重建樹的時候,可以用遞歸的方式,實現樹的後序遍歷。

#include <cstdio>
#include <cstring>
const int MAX = 10000;

int n, pos, npost;//npost後序遍歷序列中的結點個數
int pre[MAX], in[MAX], post[MAX];

void rec(int left, int right);
void solve();

int main()
{
    freopen("data.in", "r", stdin);
    freopen("data.out", "w", stdout);

    while (scanf("%d", &n) != EOF) {
        for (int i = 0; i < n; i++)
            scanf("%d", &pre[i]);
        for (int i = 0; i < n; i++)
            scanf("%d", &in[i]);
        solve();
    }

    return 0;
}

void rec(int left, int right)
{
    if (left >= right)
        return;
    int root = pre[pos++];  //取出前序遍歷中的根結點
    int mid;
    //尋找中序遍歷序列中的根結點位置
    for (mid = 0; in[mid] != root; mid++)
        ;
    rec(left, mid);      //重建左子樹
    rec(mid + 1, right); //重建右子樹
    post[npost++] = root;//將當前根結點放入後序遍歷序列中
}

void solve()
{
    pos = npost = 0;
    rec(0, n);
    for (int i = 0; i < n; i++) {
        if (i) printf(" ");
        printf("%d", post[i]);
    }
    printf("\n");
    return;
}


發佈了58 篇原創文章 · 獲贊 31 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章