给定一个插入序列就可以唯一确定一棵二叉搜索树。然而,一棵给定的二叉搜索树却可以由多种不同的插入序列得到。例如分别按照序列{2, 1, 3}和{2, 3, 1}插入初始为空的二叉搜索树,都得到一样的结果。于是对于输入的各种插入序列,你需要判断它们是否能生成一样的二叉搜索树。
输入格式:
输入包含若干组测试数据。每组数据的第1行给出两个正整数N (≤10)和L,分别是每个序列插入元素的个数和需要检查的序列个数。第2行给出N个以空格分隔的正整数,作为初始插入序列。最后L行,每行给出N个插入的元素,属于L个需要检查的序列。
简单起见,我们保证每个插入序列都是1到N的一个排列。当读到N为0时,标志输入结束,这组数据不要处理。
输出格式:
对每一组需要检查的序列,如果其生成的二叉搜索树跟对应的初始序列生成的一样,输出“Yes”,否则输出“No”。
输入样例:
4 2
3 1 4 2
3 4 1 2
3 2 4 1
2 1
2 1
1 2
0
输出样例:
Yes
No
No
思路:
先根据一个插入序列确定一颗二叉树,建树,查找余下数列的数字是否能按顺序在树上查出;(注意:别忘了查完一个序列,要给原来的树的标识清零)
代码如下:
import java.io.BufferedReader;
import java.io.FileDescriptor;
import java.io.FileReader;
public class Main {
public static void main(String[] args){
Main self = new Main();
BufferedReader br = new BufferedReader(new FileReader(FileDescriptor.in));
try {
self.readInput(br);
} catch (Exception e) {
e.printStackTrace();
}
}
public void readInput(BufferedReader br) throws Exception{
String s = "";
while ((s = br.readLine()) != null){
String[] strs = s.split(" ");
//如果是0就退出
if(strs.length==1 && Integer.parseInt(strs[0])==0){
break;
}
//不是,就读取所需要的数据
int nodeNum = Integer.parseInt(strs[0]);
int lines = Integer.parseInt(strs[1]);
String ordinary = br.readLine();
Node2 head = getTree(ordinary);
for (int i = 0; i < lines; i++) {
String temp = br.readLine();
boolean res = isSameTree(temp, head);
if (res){
System.out.println("Yes");
}else{
System.out.println("No");
}
reset(head);
}
}
}
//根据给定序列,创建一棵树
public Node2 getTree(String str){
String[] s = str.trim().split(" ");
Node2 head = new Node2(Integer.parseInt(s[0]));
for (int i = 1; i < s.length; i++) {
insertNode(head,Integer.parseInt(s[i]));
}
return head;
}
//插入节点
private Node2 insertNode(Node2 head, int val){
if (head == null){
return new Node2(val);
}else {
if (head.data > val)
head.left = insertNode(head.left,val);
else
head.right = insertNode(head.right,val);
}
return head;
}
//测试一个插入序列与另一颗树是否是同一颗树
public boolean isSameTree(String str, Node2 head){
String[] s = str.trim().split(" ");
for (int i = 0; i < s.length; i++) {
int temp = Integer.parseInt(s[i]);
if(!checkNodeHasVisit(temp,head)){
return false;
}
}
return true;
}
//测试之前结点是否已经查找过
private boolean checkNodeHasVisit(int num, Node2 head){
if (head.flag == 0){
if (num == head.data){
head.flag = 1;
return true;
}else {
return false;
}
}else {
if (num < head.data){
return checkNodeHasVisit(num, head.left);
}else if(num > head.data){
return checkNodeHasVisit(num,head.right);
}else {
return false;
}
}
}
//树的flag都清0
private void reset(Node2 head){
head.flag = 0;
if (head.left != null){
reset(head.left);
}
if (head.right != null){
reset(head.right);
}
}
}
class Node2{
int data;
Node2 left;
Node2 right;
int flag;
public Node2(int data) {
this.data = data;
this.flag = 0;
this.left = null;
this.right = null;
}
}