1043. Is It a Binary Search Tree

来源:互联网 发布:linux 终端快捷键 编辑:程序博客网 时间:2024/06/05 02:45

题目

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

基本思路

考察BST的构造、遍历等基本操作。大意为,给定一个序列,判断该序列是否为BST或镜像BST的前序序列。若是,则打印YES并输出相应的后序序列。
1.根据给定的序列构造BST,结点的插入函数如下:

void insert(node* &root,int v){    if(root == NULL){//当为空结点时,即要插入的位置         root = new node;        root->data = v;        root->lchild = root->rchild = NULL;        return;    }    if(root->data > v){//当根结点的数据域比要插入的数值更大时 ,插入左子树         insert(root->lchild,v);    }else{        insert(root->rchild,v);    }}

需要注意的是,insert(node* &root,int v) 中,根结点指针root使用了引用&(&绝对不能漏!)。引用的作用概括的说,即在函数中修改root会直接修改原变量。在insert函数中,新建的结点地址会赋给当层的root,若不使用引用,root = new node; 这个语句对root的修改就无法修改原变量,也就是不能把新结点接到二叉树的上面。一般来说,如果函数中要新建结点,即对二叉树的结构进行调整,就需要加引用;如果只是修改当前已有结点的内容或是遍历操作,则不需要引用。(关于引用的了解目前只有这么些,留空)。
2.构造好BST后,就分别对其进行先序遍历和镜像树的先序遍历(两者的操作只是访问顺序的不同),然后将遍历结果与原始序列比较。

代码
#include<cstdio>#include<vector>using namespace std;const int maxn = 1010;struct node{    int data;    node *lchild,*rchild;};int n;//结点个数 vector<int> origin,pre,preM,post,postM;//分别存放原始序列,前序序列,镜像树的前序序列,后序序列,镜像树的后序序列 //插入函数 void insert(node* &root,int v){    if(root == NULL){//当为空结点时,即要插入的位置         root = new node;        root->data = v;        root->lchild = root->rchild = NULL;        return;    }    if(root->data > v){//当根结点的数据域比要插入的数值更大时 ,插入左子树         insert(root->lchild,v);    }else{        insert(root->rchild,v);    }}//前序遍历,并将结果存放于temp中 void preOrder(node* root,vector<int>& temp){    if(root == NULL) return;    temp.push_back(root->data);    preOrder(root->lchild,temp);    preOrder(root->rchild,temp); }//镜像树的前序遍历,并将结果存放于temp中void preOrderMirror(node* root,vector<int>& temp){    if(root == NULL) return;    temp.push_back(root->data);    //先遍历右子树,即可达到镜像树的效果     preOrderMirror(root->rchild,temp);     preOrderMirror(root->lchild,temp);}//后序遍历 void postOrder(node* root,vector<int>& temp){    if(root == NULL) return;    postOrder(root->lchild,temp);    postOrder(root->rchild,temp);    temp.push_back(root->data);} //镜像树的后序遍历void postOrderMirror(node* root,vector<int>& temp){    if(root == NULL) return;    postOrderMirror(root->rchild,temp);    postOrderMirror(root->lchild,temp);    temp.push_back(root->data);} //输出函数void print(vector<int> temp){    for(int i=0;i<temp.size();i++){        printf("%d",temp[i]);        if(i < temp.size() - 1) printf(" ");        else printf("\n");    }    return;} int main(){    scanf("%d",&n);    int data;//每个结点的值     node* root = NULL; //定义根结点     for(int i=0;i<n;i++){        scanf("%d",&data);        origin.push_back(data);        insert(root,data);//把data插入树中     }       preOrder(root,pre);//前序遍历,结果存放在pre中     preOrderMirror(root,preM);//镜像树的前序遍历,结果存放在preM中     if(pre == origin){//如果原始序列即为前序序列         printf("YES\n");        postOrder(root,post);//后序遍历并输出         print(post);    }else if(preM == origin){        printf("YES\n");        postOrderMirror(root,postM);        print(postM);    }else{        printf("NO\n");    }    return 0;} 
0 0
原创粉丝点击