PAT1043 Is It a Binary Search Tree (25)(二叉查找樹BST)

類型

二叉搜索樹, 先序後序轉換

題目

A Binary Search Tree (BST) is recursively defined as a binary tree which has the following properties:

The left subtree of a node contains only nodes with keys less than the node’s key.
The right subtree of a node contains only nodes with keys greater than or equal to the node’s key.
Both the left and right subtrees must also be binary search trees.
If we swap the left and right subtrees of every node, then the resulting tree is called the Mirror Image of a BST.

Now given a sequence of integer keys, you are supposed to tell if it is the preorder traversal sequence of a BST or the mirror image of a BST.

Input Specification:

Each input file contains one test case. For each case, the first line contains a positive integer N (<=1000). Then N integer keys are given in the next line. All the numbers in a line are separated by a space.

Output Specification:

For each test case, first print in a line “YES” if the sequence is the preorder traversal sequence of a BST or the mirror image of a BST, or “NO” if not. Then if the answer is “YES”, print in the next line the postorder traversal sequence of that tree. All the numbers in a line must be separated by a space, and there must be no extra space at the end of the line.

Sample Input 1:
7
8 6 5 7 10 8 11
Sample Output 1:
YES
5 7 6 8 11 10 8
Sample Input 2:
7
8 10 11 8 6 7 5
Sample Output 2:
YES
11 8 10 7 5 6 8
Sample Input 3:
7
8 6 8 5 10 9 11
Sample Output 3:
NO
#分析題目
輸入一個先序的樹,判斷是否爲二叉搜索樹,或者是否爲二叉搜索樹的鏡像樹。

變量 意義
root 根節點
root + 1 左子樹第一個結點
tail 右子樹最後一個結點
i 右子樹第一個結點
j 左子樹最後一個結點
isMirror 是否爲鏡像二叉搜索樹的flag

利用二叉搜索樹的性質:左子樹下的所有節點比根節點要小,右子樹的所有節點節點比根節點大或者相等

  • 先通過二叉樹性質判斷是否爲先序的二叉搜索樹,如果是的話,getpost獲得的後序樹節點數等於N,否則小於N。
  • 若不爲先序的二叉搜索樹,則將isMirror設置爲true(先假設它是鏡像的二叉搜索樹),通過二叉樹性質(此時左子樹節點比根節點大或相等,右子樹節點比根節點小)判斷是否爲鏡像二叉搜索樹。

代碼

#include <iostream>
#include <vector>
using namespace std;
vector<int> pre, post;
int isMirror = 0;
void getpost(int root, int tail)
{
    if(root > tail)
        return;
    int i = root+1;
    int j = tail;
    if(!isMirror)
    {
        while(i<=tail&&pre[i]<pre[root]) i++;
        while(j> root&&pre[j]>=pre[root]) j--;
    }
    else
    {
        while(i<=tail&&pre[i]>=pre[root]) i++;
        while(j>root && pre[j]<pre[root]) j--;
    }
    getpost(root+1, j);
    getpost(i, tail);
    post.push_back(pre[root]);
}

int main()
{
    int N;
    cin >> N;
    pre.resize(N);
    for(int i = 0; i<N; i++)
    {
        cin >> pre[i];
    }
    getpost(0, N-1);
    if(post.size()!=N)
    {
        isMirror = 1;
        post.clear();
        getpost(0, N-1);
    }
    if(post.size() == N)
    {
        cout << "YES" << endl << post[0];
        for(int i=1; i<post.size(); i++)
        {
            cout << " " << post[i];
        }
    }
    else
        cout << "NO" << endl;
    return 0;
}

總結

學習了二叉搜索樹的性質,對先序和後序的轉化複習了一下,學(chao)習還是來自於柳神的代碼

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章