您的位置:首页 > 其它

PAT A 1043. Is It a Binary Search Tree (25)

2014-05-17 12:58 274 查看
题目

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


即根据输入判断是否是一颗二叉查找树的先续遍历,或者镜像的二叉查找树,

是则输出其后续遍历。

先序遍历的第一个为根,比根小的为左子树,比根大的为右子树,由此递归。

根据此性质尝试构建二叉查找树,如果不能(对某一子结构不能找出严格的左边元素都小于根,右边元素都大于根)则不是。

镜像的判断类似。注意镜像的含义,左边元素大于等于根。

代码:

#include <iostream>
using namespace std;

int flag;	//是否符合条件标志位,0符合,1不符合

struct node	//树中的点
{
int value;	//值
node *left,*right; //左右子树
};

node* Build1(int *data,int p,int q);	//是否是二叉查找树
node* Build2(int *data,int p,int q);	//镜像
void Put_data(node *root);	//输出

int main()
{
int n,data[1001];	//数据
int i;
cin>>n;
for(i=0;i<n;i++)
cin>>data[i];
if(n==1)	//只有一个值,符合条件
{
cout<<"YES\n";
cout<<data[0];
return 0;
}
flag=0;	//考虑正向
node *root=Build1(data,0,n-1);
if(flag==0)
{
cout<<"YES\n";
Put_data(root);
return 0;
}
flag=0;	//考虑镜像
root=Build2(data,0,n-1);
if(flag==0)
{
cout<<"YES\n";
Put_data(root);
}
else	//都不符合
cout<<"NO";
return 0;
}

node* Build1(int *data,int p,int q)	//数据,起始、终止位置[p,q];
{
if(p>q)
return NULL;
if(flag==1)	//不符合条件,直接跳出(应该放到最前)
return NULL;

node* root=new node;
root->value=data[p];

if(p==q)	//只有一个数
{
root->left=NULL;
root->right=NULL;
return root;
}
int i;
int r=p;	//第一个比data[p]大的数
for(i=p+1;i<=q;i++)
{
if(data[i]>=data[p])
{
r=i;
break;
}
}
if(r>p)	//找得到比data[p]大的data[r]
{
for(i=r+1;i<=q;i++)
{
if(data[i]<data[p])
{
flag=1;
return NULL;
}
}
root->left=Build1(data,p+1,r-1);
root->right=Build1(data,r,q);
}
else	//找不到
{
root->left=Build1(data,p+1,q);
root->right=NULL;
}
return root;
}

node* Build2(int *data,int p,int q)	//镜像
{
if(p>q)
return NULL;
if(flag==1)
return NULL;

node* root=new node;
root->value=data[p];

if(p==q)
{
root->left=NULL;
root->right=NULL;
return root;
}
int i;
int r=p;
for(i=p+1;i<=q;i++)
{
if(data[i]<data[p])	//注意镜像的定义
{
r=i;
break;
}
}
if(r>p)
{
for(i=r+1;i<=q;i++)
{
if(data[i]>=data[p])
{
flag=1;
return NULL;
}
}
root->left=Build2(data,p+1,r-1);
root->right=Build2(data,r,q);
}
else
{
root->left=Build2(data,p+1,q);
root->right=NULL;
}
return root;
}

int put_flag=0;	//是否输出过信息标志位,用于跳过第一个空格

void Put_data(node *root)
{
if(root->left!=NULL)
Put_data(root->left);
if(root->right!=NULL)
Put_data(root->right);
if(put_flag==1)
cout<<" ";
else
put_flag=1;
cout<<root->value;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: