給定一個插入序列就可以唯一确定一棵二叉搜尋樹。然而,一棵給定的二叉搜尋樹卻可以由多種不同的插入序列得到。例如分别按照序列{2, 1, 3}和{2, 3, 1}插入初始為空的二叉搜尋樹,都得到一樣的結果。于是對于輸入的各種插入序列,你需要判斷它們是否能生成一樣的二叉搜尋樹。
輸入格式:
輸入包含若幹組測試資料。每組資料的第1行給出兩個正整數NN (\le 10≤10)和LL,分别是每個序列插入元素的個數和需要檢查的序列個數。第2行給出NN個以空格分隔的正整數,作為初始插入序列。最後LL行,每行給出NN個插入的元素,屬于LL個需要檢查的序列。
簡單起見,我們保證每個插入序列都是1到NN的一個排列。當讀到NN為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
求解思路
兩個序列是否對應相同搜尋樹的判别
1.分别建兩棵搜尋樹的判别方法
2.不建樹的判别方法
3. 建一棵樹,再判别其他序列是否與該樹一緻
1. 搜尋樹表示
2. 建搜尋樹T
3. 判别一序列是否與搜尋樹T一緻
/*!
* \file 04-樹4 是否同一棵二叉搜尋樹.cpp
*
* \author ranjiewen
* \date 三月 2017
*
*
*/
//兩個序列是否對應相同搜尋樹的判别
//1.分别建兩棵搜尋樹的判别方法
//2.不建樹的判别方法
//3. 建一棵樹,再判别其他序列是否與該樹一緻
#include <stdio.h>
#include <stdlib.h>
typedef int Status; //函數類型
typedef int ElementType;
typedef struct TreeNode* BSTree;
struct TreeNode
{
ElementType Data;
BSTree Left;
BSTree Right;
int Flag; //被通路為1,否則0
};
BSTree NewNode(ElementType data);
BSTree Insert(BSTree T, ElementType data);
BSTree MakeTree(int N);
bool Check(BSTree T,ElementType data);
int Judge(BSTree T);
void ResetT(BSTree T);
void FreeT(BSTree T);
BSTree NewNode(ElementType data)
{
BSTree root = (BSTree)malloc(sizeof(struct TreeNode));
root->Data = data;
root->Left = NULL;
root->Right = NULL;
root->Flag = 0;
return root;
}
BSTree Insert(BSTree root, ElementType data)
{
if (root==NULL)
{
root = NewNode(data);
}
else
{
if (root->Data < data)
{
root->Right = Insert(root->Right, data);
}
else
{
root->Left = Insert(root->Left, data);
}
}
return root;
}
BSTree MakeTree(int N)
{
BSTree T;
ElementType data;
scanf("%d", &data);
T = NewNode(data);
for (int i = 1; i < N; i++)
{
scanf("%d", &data);
T = Insert(T, data);
}
return T;
}
//将另一棵樹的結點依次在一顆二叉樹上搜尋,找到後标記;當搜尋過程中有未被标記的結點,說明兩棵樹不一樣
bool Check(BSTree T, ElementType data)
{
if (T->Flag)
{
if (data<T->Data)
{
return Check(T->Left, data);
}
else
{
return Check(T->Right, data);
}
}
else
{
if (data==T->Data)
{
T->Flag = 1;
return true;
}
else
{
return false; //結點不一緻
}
}
}
int Judge(BSTree T, int N)
{
ElementType data;
int flag = 0; //0代表目前乃一緻,1代表已經不一緻
scanf("%d", &data);
if (data!=T->Data) //判斷根結點是否一緻
{
flag = 1; //不一緻的情況下也要把後面的結點輸入後才做判斷
}
else T->Flag = 1;
for (int i = 1; i < N; i++)
{
scanf("%d", &data);
if ((!flag)&&(!Check(T,data)))
{
flag = 1;
}
}
if (flag)
{
return 0;
}
else
return 1;
}
void ResetT(BSTree T) //清除T中各結點的flag标記
{
if (T->Left)
{
ResetT(T->Left);
}
if (T->Right)
{
ResetT(T->Right);
}
T->Flag = 0;
}
void FreeT(BSTree T) //釋放T的空間
{
if (T->Left)
{
FreeT(T->Left);
}
if (T->Right)
{
FreeT(T->Right);
}
free(T);
}
int main()
{
int N;
int L;
BSTree T;
scanf("%d", &N);
while (N) //可以多次輸入測試
{
scanf("%d", &L); //需要檢查的序列個數
T = MakeTree(N); //輸入N個元素建立樹
for (int i = 0; i < L;i++) //對每個序列操作
{
if (Judge(T, N)) //依次輸入N個元素,每個元素都進行标記判斷
{
printf("Yes\n");
}
else
{
printf("No\n");
}
ResetT(T);
}
FreeT(T);
scanf("%d", &N);
}
}
C/C++基本文法學習
STL
C++ primer