Back to Ladder-L2-004 Is this a binary search tree? (25 points)

Topic description

A binary search tree can be defined recursively as a binary tree with the following properties: For any node,

  • The key value of all nodes in its left subtree is less than the key value of this node;
  • The key value of all nodes in its right subtree is greater than or equal to the key value of this node;
  • Its left and right subtrees are binary search trees.
  • The so-called "mirror" of a binary search tree is a tree obtained by reversing the positions of the left and right subtrees of all nodes.

Given a sequence of integer keys, please write a program to determine whether this is the result of a preorder traversal of a binary search tree or its mirror image.

Input format:

The first line of input gives a positive integer N (≤1000). The next line gives N integer key values ​​separated by spaces.

Output format:

If the input sequence is the result of a preorder traversal of a binary search tree or its mirror image, output YES on one line first, and then output the result of a postorder traversal of the tree on the next line. There should be 1 space between numbers, and there should be no extra spaces at the beginning and end of a line. If the answer is no, output NO.

Input sample 1:

7
8 6 5 7 10 8 11

Sample output 1:

YES
5 7 6 8 11 10 8

Pre-order judgment BST + pre-middle generation post-order

First of all, this question has two predecessor questions
18. Rebuild binary tree
46. Post-order traversal sequence of binary search tree After
completing these two questions and writing this question again, you will write this 80-line
code. Although the code is complex, it is complex. Very useful. There are some spellings worth keeping

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

const int N = 1010;
int n;
vector<int> pre;
vector<int> in;// 树的中序
int post[N], top;
bool isMirror;

// 根据前序序列判断是否为二叉搜索树
bool isSearch(int l, int r) {
    
    
    if (l >= r) return true;
    
    int root = pre[l];
    int k = l + 1;
    while (k <= r && pre[k] < root) k++;
    for (int i = k; i <= r; i++)
        if (pre[i] < root) return false;
    
    return isSearch(l+1, k-1) && isSearch(k, r);
}

// 根据前序序列判断是否为二叉镜向搜索树
bool isSearch2(int l, int r) {
    
    
    if (l >= r) return true;
    
    int root = pre[l];
    int k = l + 1;
    while (k <= r && pre[k] >= root) k++;
    for (int i = k; i <= r; i++)
        if (pre[i] > root) return false;
    
    return isSearch2(l+1, k-1) && isSearch2(k, r);
}

// 利用前序和中序序列,求解后序序列。不能处理有数重复的问题,会导致建的树与原先不符
void build(int pl, int pr, int il, int ir) {
    
    
    if (pl > pr || il > ir) 
        return;

    int k = il;
    if (!isMirror) while(k <= ir && in[k] < pre[pl]) k++;
    else {
    
    
        while(k <= ir && in[k] >= pre[pl]) k++;
        k--;
    }
    k -= il; // 左子树的大小
    build(pl + 1, pl + k, il, il + k-1);
    build(pl + k + 1, pr, il + k + 1, ir);
    
    post[top] = pre[pl];
    top++;
}

bool cmp(int a, int b) {
    
    
    return a > b;
}

int main() {
    
    
    cin >> n;
    
    for (int i = 0; i < n; i++) {
    
    
        int x;
        cin >> x;
        pre.push_back(x);
    }
    
    
    if (isSearch(0, pre.size()-1) || isSearch2(0, pre.size()-1)) {
    
    
        puts("YES");
        
        in = pre; 
        if (isSearch(0, pre.size()-1)) {
    
    
            sort(in.begin(), in.end());
            isMirror = false;
        }
        else {
    
    
            sort(in.begin(), in.end(), cmp);
            isMirror = true;
        }
        build(0, n-1, 0, n-1);
        printf("%d", post[0]);
        for (int i = 1; i < n; i++) printf(" %d", post[i]);
        cout << endl;
        
    } else puts("NO");
    
    return 0;
}

Thanks to my friend tw for helping me debug. It turned out that there were several borders that were not handled properly, only 15 points, thank you very much! ! !

L2-004 Is this a binary search tree? (25 points)

The preorder of BST properties is directly transferred to the postorder

#include <iostream>
#include <vector>

using namespace std;
vector<int> pre, post;
int n;
bool isMirror;

void getpost(int l, int r) {
    
    
    if (l > r) return;
    int i = l + 1, j = r;
    
    int root = pre[l];
    if (!isMirror) {
    
    
        while (i <= r && pre[i] < root) i++;
        while (j > l && pre[j] >= root) j--;
    } else {
    
    
        while (i <= r && pre[i] >= root) i++;
        while (j > l && pre[j] < root) j--;
    }
    if (i - j != 1) return;
    getpost(l + 1, j);
    getpost(i, r);
    
    post.push_back(pre[l]);
}

int main () {
    
    
    cin >> n;
    
    for (int i = 0; i < n; i++) {
    
    
        int x;
        cin >> x;
        pre.push_back(x);
    }
    
    // 假设是二叉搜索树
    getpost(0, pre.size()-1);
    
    // 二叉搜索树条件不满足,假设是镜向树
    if (post.size() < n) {
    
    
        isMirror = true;
        post.clear();
        getpost(0, pre.size()-1);
    } 
    
    if (post.size() == n) {
    
    
        puts("YES");
        cout << post[0];
        for (int i = 1; i < post.size(); i++) printf(" %d", post[i]);
    } else puts("NO");
    
    return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324189426&siteId=291194637