1119 Pre- and Post-order Traversals (30point(s)) - C語言 PAT 甲級

1119 Pre- and Post-order Traversals (30point(s))

Suppose that all the keys in a binary tree are distinct positive integers. A unique binary tree can be determined by a given pair of postorder and inorder traversal sequences, or preorder and inorder traversal sequences. However, if only the postorder and preorder traversal sequences are given, the corresponding tree may no longer be unique.

Now given a pair of postorder and preorder traversal sequences, you are supposed to output the corresponding inorder traversal sequence of the tree. If the tree is not unique, simply output any one of them.

Input Specification:

Each input file contains one test case. For each case, the first line gives a positive integer N (≤ 30), the total number of nodes in the binary tree. The second line gives the preorder sequence and the third line gives the postorder sequence. All the numbers in a line are separated by a space.

Output Specification:

For each test case, first printf in a line Yes if the tree is unique, or No if not. Then print in the next line the inorder traversal sequence of the corresponding binary tree. If the solution is not unique, any answer would do. It is guaranteed that at least one solution exists. All the numbers in a line must be separated by exactly one space, and there must be no extra space at the end of the line.

Sample Input:

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

Sample Output:

Yes
2 1 6 4 7 3 5

Sample Input:

4
1 2 3 4
2 4 3 1

Sample Output:

No
2 1 3 4

題目大意:

有 N 個節點的樹,並給出先序遍歷和後序遍歷,

輸出中序遍歷,若中序遍歷唯一輸出 Yes,若不唯一輸出 No,且只輸出其中任意一箇中序

設計思路:

重點在於理解先序和後序無法得到唯一中序的原因

  • 先序遍歷,中左右
  • 後序遍歷,左右中
  • 每次遍歷到根節點中時,需要確定左右子樹,
    • 假設以先序的左找後序的左
    • 若後序的左和中之間有節點,說明中間節點即爲右子樹,所以能唯一確定左右子樹
    • 若後序的左和中之間沒有節點,那這個左節點既可以當左子樹根,也可以當右子樹根,出現了不唯一
一、
先根序列:1 2 3(中左右順序)

後根序列:2 3 1(左右中順序)

可以確定 1 是整棵樹的根節點,
假設以先序的左找後序的左,
先序左根爲 2,後序左根 2 和根節點 1 之間有 3,
那麼 3 一定只能是右根,唯一確定一顆樹
  1
2   3

二、
先根序列:1 2 3(中左右順序)

後根序列:3 2 1(左右中順序)

可以確定 1 是整棵樹的根節點,假設以先序的左找後序的左,左根爲 2,後序左根 2 和根節點 1 之間沒有節點,
那麼 2 可以是右根,根節點 1 沒有左根
或,那麼 2 可以是左根,根節點 1 沒有右根
 11
   2          2
先根序列:2 3(中左右順序)
後根序列:3 2(左右中順序)
此時同理, 3 可以是右根,也可以是左根
 1111
   2                2            2               2
     3            3                3           3   
最終會有四個形態
編譯器:C (gcc)
include <stdio.h>

int n, pre[30], post[30];
int in[30], cnt = 0, flag = 1;

void inorder(int iroot, int left, int right)
{
        if (left >= right) {
                if (left == right)
                        in[cnt++] = pre[iroot];
                return ;
        }
        int i = left;
        while (i < right && post[i] != pre[iroot + 1])
                i++;
        if (i == right - 1)
                flag = 0;
        inorder(iroot + 1, left, i);
        in[cnt++] = pre[iroot];
        inorder(iroot + 1+ i - left + 1, i + 1, right - 1);
}

int main(void)
{
        int i;

        scanf("%d", &n);
        for (i = 0; i < n; i++)
                scanf("%d", &pre[i]);
        for (i = 0; i < n; i++)
                scanf("%d", &post[i]);
        inorder(0, 0, n - 1);
        printf("%s\n", flag ? "Yes" : "No");
        for (i = 0; i < n; i++)
                printf("%s%d", i > 0 ? " " : "", in[i]);
        printf("\n");
        return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章