https://pintia.cn/problem-sets/994805342720868352/problems/994805440976633856
题意:给你一组前序遍历的结果,看是否能建成二叉搜索树或其镜像,若是则输出后序遍历输出。
思路:首先注意这个二叉排序树大于等于为右子树,小于为左子树。然后由于我们已知二叉排序树中序序列(升序),故只需要知道前序序列即可建树。不过这题还要判断前序序列是否合法,判断标准就是把前序序列拆成根、左子树、右子树,之后判断右子树中是否有非法元素(即左子树中的元素),然后不断递归即可判断。因为还要判断镜像,所以每种函数也要弄个镜像。
总体来说这题考查对前序序列的理解。
#include <cstdio> #include <iostream> #include <algorithm> #include <string> #include <cstring> #include <vector> #include <stack> #include <queue> #include <cmath> #include <climits> using namespace std; const int MAXN = 1005; const int INF = INT_MAX; struct Treenode{ int data; Treenode* leftchild; Treenode* rightchild; Treenode(int d) : data(d), leftchild(NULL), rightchild(NULL) {} }; int seq[MAXN], N; bool check1(int start, int end, int x){ if(start > end) return true; int i, j; for(i = start; i <= end; i++){ if(seq[i] >= x) break; } for(j = i; j <= end; j++){ if(seq[j] < x) break; } if(j != (end + 1)) return false; if(check1(start + 1, i - 1, seq[start]) == true && check1(i + 1, end, seq[i]) == true) return true; else return false; } bool check2(int start, int end, int x){ if(start > end) return true; int i, j; for(i = start; i <= end; i++){ if(seq[i] < x) break; } //printf("....%d\n", i); for(j = i; j <= end; j++){ if(seq[j] >= x) break; } //printf("....%d\n", j); if(j != (end + 1)) return false; if(check2(start + 1, i - 1, seq[start]) == true && check2(i + 1, end, seq[i]) == true) return true; else return false; } Treenode* Insert1(Treenode* root, int value){ if(root == NULL){ root = new Treenode(value); return root; } if(value < root->data) root->leftchild = Insert1(root->leftchild, value); if(value >= root->data) root->rightchild = Insert1(root->rightchild, value); return root; } Treenode* Insert2(Treenode* root, int value){ if(root == NULL){ root = new Treenode(value); return root; } if(value >= root->data) root->leftchild = Insert2(root->leftchild, value); if(value < root->data) root->rightchild = Insert2(root->rightchild, value); return root; } void PreOrder(Treenode* root, bool &flag){ if(root == NULL) return; PreOrder(root->leftchild, flag); PreOrder(root->rightchild, flag); if(flag) printf(" "); flag = true; printf("%d", root->data); return; } int main(){ // freopen("in.txt", "r", stdin); while(~scanf("%d", &N)){ int kind;//1为正常树,2为镜像树 for(int i = 0; i < N; i++){ scanf("%d", &seq[i]); } if(seq[1] < seq[0]) kind = 1; else kind = 2; if(kind == 1){ if(check1(1, N - 1, seq[0])) printf("YES\n"); else{ printf("NO\n"); continue; } Treenode* root = NULL; for(int j = 0; j < N; j++){ root = Insert1(root, seq[j]); } bool flag = false; PreOrder(root, flag); printf("\n"); } else if(kind == 2){ if(check2(1, N - 1, seq[0])) printf("YES\n"); else{ printf("NO\n"); continue; } Treenode* root = NULL; for(int j = 0; j < N; j++){ root = Insert2(root, seq[j]); } bool flag = false; PreOrder(root, flag); printf("\n"); } } return 0; }