データ構造(陳越、何欽銘)--第四周のプログラミング作業
45258 ワード
04-木4は同一の二叉検索ツリーかどうか(25分)
挿入されたシーケンスを指定すると、一本の二叉検索ツリーを一意に決定することができます.しかし、与えられた一本の二叉検索ツリーは、複数の異なる挿入シーケンスから得ることができる.例えば、最初に空だった二叉探索ツリーをシーケンス{2,1,3}と{2,3,1}で挿入すると、同じ結果が得られる.入力された各種の挿入シーケンスについては、同じツリーを生成できるかどうかを判断する必要があります.
入力形式:いくつかのグループのテストデータを入力します.各データの1行目は、2つの正の整数N(≦10)とLを与え、それぞれのシーケンス挿入要素の個数と検査が必要なシーケンス個数である.2行目は、最初の挿入シーケンスとして、N個のスペースで区切られた正の整数を与えます.最後のL行は、行ごとにN個の挿入要素を与え、L個の検査が必要なシーケンスに属する.
簡単のために、各挿入シーケンスは1からNまでの配列であることを保証します.Nが0であるとフラグ入力が終了します.このデータは処理しません.
出力フォーマット:各グループのチェックが必要なシーケンスに対して、生成された二叉検索ツリーが対応する初期シーケンスと同じ場合、「Yes」を出力します.そうでなければ、「No」を出力します.
入力例:4 2 3 1 4 4 4 4 1 2 2 4 1 2 1 2 1 2 1 2 2 2 2 0出力例:Yes No.
本題は与えられた二叉検索ツリーの5種類の常用操作を実現することを要求します.
関数インターフェースの定義:
審判試験手順の例:
10 5 8 6 2 4 1 0 10 7 5 3 10 5 5 5 5 5 7 0 10 3
出力例:
Prorder:5 2 1 0 4 7 7 10 6 is found 3 is not found 10 is found 10 is the larget key 0 is found 0 is the smalest key 5 is found Not Found Inorder:1 2 4 6 8 9
挿入されたシーケンスを指定すると、一本の二叉検索ツリーを一意に決定することができます.しかし、与えられた一本の二叉検索ツリーは、複数の異なる挿入シーケンスから得ることができる.例えば、最初に空だった二叉探索ツリーをシーケンス{2,1,3}と{2,3,1}で挿入すると、同じ結果が得られる.入力された各種の挿入シーケンスについては、同じツリーを生成できるかどうかを判断する必要があります.
入力形式:いくつかのグループのテストデータを入力します.各データの1行目は、2つの正の整数N(≦10)とLを与え、それぞれのシーケンス挿入要素の個数と検査が必要なシーケンス個数である.2行目は、最初の挿入シーケンスとして、N個のスペースで区切られた正の整数を与えます.最後のL行は、行ごとにN個の挿入要素を与え、L個の検査が必要なシーケンスに属する.
簡単のために、各挿入シーケンスは1からNまでの配列であることを保証します.Nが0であるとフラグ入力が終了します.このデータは処理しません.
出力フォーマット:各グループのチェックが必要なシーケンスに対して、生成された二叉検索ツリーが対応する初期シーケンスと同じ場合、「Yes」を出力します.そうでなければ、「No」を出力します.
入力例:4 2 3 1 4 4 4 4 1 2 2 4 1 2 1 2 1 2 1 2 2 2 2 0出力例:Yes No.
#include
#include
typedef struct TreeNode *Tree;
struct TreeNode
{
int Data;
Tree Left;
Tree Right;
int flag;
};
Tree BuildTree(int N);
int Judge(Tree T, int N);
void ResetFlag(Tree T);
void FreeTree(Tree T);
Tree NewNode(int node);
Tree Insert(Tree T, int node);
int Check(Tree T, int node);
int main()
{
int N, L, i;
Tree T;
scanf("%d", &N);
while(N)
{
scanf("%d", &L);
T = BuildTree(N);
for(i = 0; i < L; i++)
{
if(Judge(T, N))
printf("Yes
");
else
printf("No
");
ResetFlag(T);
}
FreeTree(T);
scanf("%d", &N);
}
return 0;
}
Tree BuildTree(int N)
{
Tree T;
int i, node;
scanf("%d", &node);
T = NewNode(node);
for(i = 1; i < N; i++)
{
scanf("%d", &node);
T = Insert(T, node);
}
return T;
}
Tree NewNode(int node)
{
Tree T;
T = (Tree)malloc(sizeof(struct TreeNode));
T->Data = node; T->flag = 0; T->Left = T->Right = NULL;
return T;
}
Tree Insert(Tree T, int node)
{
if(!T) T = NewNode(node);
else{
if(node > T->Data)
T->Right = Insert(T->Right, node);
else
T->Left = Insert(T->Left, node);
}
return T;
}
int Judge(Tree T, int N)
{
int i, node;
int flag = 0;
scanf("%d", &node);
if(node != T->Data) flag = 1;
else T->flag = 1;
for(i = 1; i < N; i++){
scanf("%d", &node);
if((!flag) && (!Check(T, node))) flag = 1;
}
if(flag) return 0;
else return 1;
}
int Check(Tree T, int node)
{
if(T->flag){
if(node < T->Data) return Check(T->Left, node);
else if(node > T->Data) return Check(T->Right, node);
else return 0;
}
else{
if(node == T->Data){
T->flag = 1;
return 1;
}
else return 0;
}
}
void ResetFlag(Tree T)
{
if(T->Left) ResetFlag(T->Left);
if(T->Right) ResetFlag(T->Right);
T->flag = 0;
}
void FreeTree(Tree T)
{
if(T->Left) FreeTree(T->Left);
if(T->Right) FreeTree(T->Right);
free(T);
}
04-ツリー7二叉検索ツリーの操作セット(30分)本題は与えられた二叉検索ツリーの5種類の常用操作を実現することを要求します.
関数インターフェースの定義:
BinTree Insert( BinTree BST, ElementType X );
BinTree Delete( BinTree BST, ElementType X );
Position Find( BinTree BST, ElementType X );
Position FindMin( BinTree BST );
Position FindMax( BinTree BST );
BinTree構造の定義は以下の通りである.typedef struct TNode *Position;
typedef Position BinTree;
struct TNode{
ElementType Data;
BinTree Left;
BinTree Right;
};
関数Insertは、Xを二叉検索ツリーBSTに挿入し、結果ツリーのルートノードポインタを返します.関数Deleteは、Xを二叉検索ツリーBSTから削除し、結果ツリーのルートノードポインタを返します.Xがツリー内にない場合、Not Found行を印刷して元のツリーのルートノードポインタに戻ります.関数Findは、二叉検索ツリーBSTにXを見つけ、そのノードのポインタを返します.見つけられない場合は空のポインタを返します.関数FindMinは、二叉検索ツリーBSTの最小要素ノードのポインタを返します.関数FindMaxは、二叉検索ツリーBSTの中の最大の要素ノードのポインタを返します.審判試験手順の例:
#include
#include
typedef int ElementType;
typedef struct TNode *Position;
typedef Position BinTree;
struct TNode{
ElementType Data;
BinTree Left;
BinTree Right;
};
void PreorderTraversal( BinTree BT ); /* , , */
void InorderTraversal( BinTree BT ); /* , , */
BinTree Insert( BinTree BST, ElementType X );
BinTree Delete( BinTree BST, ElementType X );
Position Find( BinTree BST, ElementType X );
Position FindMin( BinTree BST );
Position FindMax( BinTree BST );
int main()
{
BinTree BST, MinP, MaxP, Tmp;
ElementType X;
int N, i;
BST = NULL;
scanf("%d", &N);
for ( i=0; i<N; i++ ) {
scanf("%d", &X);
BST = Insert(BST, X);
}
printf("Preorder:"); PreorderTraversal(BST); printf("
");
MinP = FindMin(BST);
MaxP = FindMax(BST);
scanf("%d", &N);
for( i=0; i<N; i++ ) {
scanf("%d", &X);
Tmp = Find(BST, X);
if (Tmp == NULL) printf("%d is not found
", X);
else {
printf("%d is found
", Tmp->Data);
if (Tmp==MinP) printf("%d is the smallest key
", Tmp->Data);
if (Tmp==MaxP) printf("%d is the largest key
", Tmp->Data);
}
}
scanf("%d", &N);
for( i=0; i<N; i++ ) {
scanf("%d", &X);
BST = Delete(BST, X);
}
printf("Inorder:"); InorderTraversal(BST); printf("
");
return 0;
}
/* */
入力サンプル:10 5 8 6 2 4 1 0 10 7 5 3 10 5 5 5 5 5 7 0 10 3
出力例:
Prorder:5 2 1 0 4 7 7 10 6 is found 3 is not found 10 is found 10 is the larget key 0 is found 0 is the smalest key 5 is found Not Found Inorder:1 2 4 6 8 9
BinTree Insert( BinTree BST, ElementType X )
{
if(!BST){
BST = (BinTree)malloc(sizeof(struct TNode));
BST->Data = X;
BST->Left = BST->Right = NULL;
}else{
if(X >= BST->Data){
BST->Right = Insert(BST->Right, X);
}else
BST->Left = Insert(BST->Left, X);
}
return BST;
}
BinTree Delete( BinTree BST, ElementType X )
{
Position item;
if(!BST){
printf("Not Found
");
}else{
if(X > BST->Data) BST->Right = Delete(BST->Right, X);
else if(X < BST->Data) BST->Left = Delete(BST->Left, X);
else{
if((BST->Left)&&(BST->Right)){
item = FindMin(BST->Right);
BST->Data = item->Data;
BST->Right = Delete(BST->Right, BST->Data);
}
else{
item = BST;
if(!BST->Left) BST = BST->Right;
else if(!BST->Right) BST = BST->Left;
free(item);
}
}
}
return BST;
}
Position Find( BinTree BST, ElementType X )
{
if(!BST) return NULL;
else{
if(X == BST->Data) return BST;
else if(X > BST->Data) return Find(BST->Right, X);
else return Find(BST->Left, X);
}
}
Position FindMin( BinTree BST )
{
if(BST){
while(BST->Left) BST = BST->Left;
}
return BST;
}
Position FindMax( BinTree BST )
{
if(BST){
while(BST->Right) BST = BST->Right;
}
return BST;
}