04-树4 是否同一棵二叉搜索树 (25 分)

给定一个插入序列就可以唯一确定一棵二叉搜索树。然而,一棵给定的二叉搜索树却可以由多种不同的插入序列得到。例如分别按照序列{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

我们知道,**如果知道了一棵树的先序遍历和中序遍历,便可以唯一确定一棵树,**而对于本题中二叉搜索树,中序遍历都是一样的,所以我们只需要对比各树的先序遍历是否一样,便可以判断是否是同一颗二叉搜索树。

代码如下

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>

#define MAXSIZE 10

typedef int ElementType;
typedef struct TNode* Position;
typedef Position BinTree;
struct TNode {
	ElementType Data;
	BinTree Left;
	BinTree Right;
};

BinTree Insert(BinTree BST, ElementType X);
BinTree Delete(BinTree BST, ElementType X);
Position FindMin(BinTree BST);
void PreOrderTraversal(BinTree T, int* a);
void InOrderTraversal(BinTree T, int* a);

typedef struct SNode* Stack;
struct SNode
{
	Position data[MAXSIZE];
	int top;
};

Stack CreateStack()int IsEmpty(Stack S)int Push(Stack S, Position data);
Position Pop(Stack S)//树和栈都由我们自己定义
int main()
{
	BinTree BST;
	BinTree BSTcheck[100];
	ElementType X;
	int N, i, L, j;
	BST = NULL;
	for (i = 0; i < 100; ++i)
	{
		BSTcheck[i] = NULL;
	}
	int binordert[MAXSIZE];
	int bcheckinordert[100][MAXSIZE];
	

	while (1)
	{
		scanf("%d", &N);
		if (N == 0)
			break;
		else
		{
			scanf("%d", &L);
			for (i = 0; i < N; i++)
			{
				scanf("%d", &X);
				BST = Insert(BST, X);
			}
			PreOrderTraversal(BST, binordert);	//将先序遍历存入数组binordert
			for (j = 0; j < L; ++j)
			{
				for (i = 0; i < N; i++)
				{
					scanf("%d", &X);
					BSTcheck[j] = Insert(BSTcheck[j], X);
				}
				PreOrderTraversal(BSTcheck[j], bcheckinordert[j]);
			}

			for (j = 0; j < L; ++j)
			{
				for (i = 0; i < N; ++i)
				{
					if (binordert[i] != bcheckinordert[j][i])
					{
						printf("No\n");
						break;
					}
					else if(i == N-1)
					{
						printf("Yes\n");
					}
				}
			}
			for (i = 1; i <= N; ++i)
			{
				BST = Delete(BST, i);
			}
			for (j = 0; j < L; ++j)
			{
				for (i = 1; i <= N; ++i)
				{
					BSTcheck[j] = Delete(BSTcheck[j], i);
				}
			}
		}
	}
	return 0;
}

Stack CreateStack()
{
	Stack S;
	S = (Stack)malloc(sizeof(struct SNode));
	S->top = -1;
	return S;
}

int IsEmpty(Stack S)
{
	if (S->top == -1)
		return 1;
	else
		return 0;
}

int Push(Stack S, Position data)
{
	if (S->top == MAXSIZE - 1)
	{
		printf("栈满");
		return 0;
	}
	else
	{
		++S->top;
		S->data[S->top] = data;

		return 1;
	}
}

Position Pop(Stack S)
{
	Position data;
	if (IsEmpty(S))
	{
		printf("栈空");
		return NULL;
	}
	else
	{
		data = S->data[S->top];
		--S->top;
		return data;
	}
}


Position FindMin(BinTree BST)
{
	Position P;
	P = BST;
	if (P == NULL)
		return NULL;
	else
		while (P->Left != NULL)
		{
			P = P->Left;
		}
	return P;
}

BinTree Insert(BinTree BST, ElementType X)
{
	if (BST == NULL)
	{
		BST = (BinTree)malloc(sizeof(struct TNode));
		BST->Data = X;
		BST->Left = NULL;
		BST->Right = NULL;
	}
	else
	{
		Position P;
		P = BST;
		while (1)
		{
			if (X > P->Data)
			{
				if (P->Right != NULL)
					P = P->Right;
				else
				{
					P->Right = (BinTree)malloc(sizeof(struct TNode));
					P->Right->Data = X;
					P->Right->Left = NULL;
					P->Right->Right = NULL;
					break;
				}
			}
			else
			{
				if (P->Left != NULL)
					P = P->Left;
				else
				{
					P->Left = (BinTree)malloc(sizeof(struct TNode));
					P->Left->Data = X;
					P->Left->Left = NULL;
					P->Left->Right = NULL;
					break;
				}
			}
		}
	}
	return BST;

}

BinTree Delete(BinTree BST, ElementType X)
{
	Position p;
	ElementType t;
	if (BST == NULL)
	{
		printf("Not Found\n");
		return NULL;
	}
	else
	{
		if (X < BST->Data)
		{
			if (BST->Left == NULL)
			{
				printf("Not Found\n");
				return BST;
			}
			else
			{
				BST->Left = Delete(BST->Left, X);
				return BST;
			}
		}
		else if (X > BST->Data)
		{
			if (BST->Right == NULL)
			{
				printf("Not Found\n");
				return BST;
			}
			else
			{
				BST->Right = Delete(BST->Right, X);
				return BST;
			}
		}
		else
		{
			if (BST->Left == NULL && BST->Right == NULL)
			{
				free(BST);
				return NULL;
			}
			else if (BST->Left == NULL && BST->Right != NULL)
			{
				p = BST;
				BST = BST->Right;
				free(p);
				return BST;
			}
			else if (BST->Left != NULL && BST->Right == NULL)
			{
				p = BST;
				BST = BST->Left;
				free(p);
				return BST;
			}
			else
			{
				t = FindMin(BST->Right)->Data;
				BST->Data = t;
				BST->Right = Delete(BST->Right, t);
				return BST;
			}
		}
	}
}


void PreOrderTraversal(BinTree T, int* a)
{
	int i = 0;
	Stack S;
	S = CreateStack();
	while (T != NULL || !IsEmpty(S))
	{
		if (T != NULL)
		{
			a[i] = T->Data;
			++i;
			Push(S, T);
			T = T->Left;
		}
		else
		{
			T = Pop(S);
			T = T->Right;
		}
	}
	free(S);
}

void InOrderTraversal(BinTree T, int* a)
{
	int i = 0;
	Stack S;
	S = CreateStack();
	while (T != NULL || !IsEmpty(S))
	{
		if (T != NULL)
		{
			
			Push(S, T);
			T = T->Left;
		}
		else
		{
			T = Pop(S);
			a[i] = T->Data;
			++i;
			T = T->Right;
		}
	}
	free(S);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值