第四次编程作业





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


给定一个插入序列就可以唯一确定一棵二叉搜索树。然而,一棵给定的二叉搜索树却可以由多种不同的插入序列得到。例如分别按照序列{2, 1, 3}和{2, 3, 1}插入初始为空的二叉搜索树,都得到一样的结果。于是对于输入的各种插入序列,你需要判断它们是否能生成一样的二叉搜索树。

输入格式:

输入包含若干组测试数据。每组数据的第1行给出两个正整数NNN (≤10\le 1010)和LLL,分别是每个序列插入元素的个数和需要检查的序列个数。第2行给出NNN个以空格分隔的正整数,作为初始插入序列。最后LLL行,每行给出NNN个插入的元素,属于LLL个需要检查的序列。

简单起见,我们保证每个插入序列都是1到NNN的一个排列。当读到NNN为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


#include 
#include 
#define ElementType int

typedef struct Node *Tree;
struct Node{
	ElementType Element;
	Tree Left;
	Tree Right;
	int Flag;
};

Tree BuildTree(int);
Tree CreateNewNode(int);
Tree Insert(Tree, int);
int Judge(Tree, int);
int Check(Tree, int);
void Reset(Tree);
void FreeTree(Tree);

int main()
{
	int N, L, i;
	Tree T;
	
	scanf("%d", &N);
	while (N){
		scanf("%d", &L);
		int Result[L];
		T = BuildTree(N);
		
		for(i = 0; i < L; i++){
			Result[i] = Judge(T, N);
			Reset(T);
		}
		
		for(i = 0; i < L; i++){
			if(Result[i] == 1)
				printf("Yes\n");
			else
				printf("No\n");	
		}
		FreeTree(T);
		scanf("%d", &N);
	}
	return 0;
}

Tree BuildTree(int N)
{
	int i, data;
	Tree T;
	
	scanf("%d", &data);
	T = CreateNewNode(data);
	for(i = 1; i < N; i++){
		scanf("%d", &data);
		T = Insert(T, data);
	}
	
	return T;
}

Tree CreateNewNode(int data)
{
	Tree T = (Tree)malloc(sizeof(struct Node));
	T->Element = data;
	T->Left = NULL;
	T->Right = NULL;
	T->Flag = 0;
	
	return T;
}

Tree Insert(Tree T, int data)
{
	if(!T)
		T = CreateNewNode(data);
	else{
		if(data < T->Element)
			T->Left = Insert(T->Left, data);
		else if(data > T->Element)
			T->Right = Insert(T->Right, data);
	}
		
	return T;			
}

int Judge(Tree T, int N)
{
	int i, data;
	int flag = 1;
	
	scanf("%d", &data);
	if(data != T->Element)
		return 0;
	else
		T->Flag = 1;	
	
	//flag = 1代表正常 flag = 0 代表不匹配 
	for(i = 1; i < N; i++){
		scanf("%d", &data);
		flag = Check(T, data);
		if(!flag)
			break;
	}
	return flag;
}

//返回1当前结点代表匹配 
int Check(Tree T, int data)
{	
	if(T->Flag){
		if(data < T->Element)
			return Check(T->Left, data);
		else if(data > T->Element)
			return Check(T->Right, data);
		else
			return 0;	
	}
	else{
		if(data == T->Element){
			T->Flag = 1;
			return 1;
		}
		else
			return 0;
	}
				
}

void Reset(Tree T)
{
	if(T->Left)
		Reset(T->Left);
	if(T->Right)
		Reset(T->Right);
		
	T->Flag = 0;		
}

void FreeTree(Tree T)
{
	if(T->Left)
		FreeTree(T->Left);
	if(T->Right)
		FreeTree(T->Right);
	
	free(T);		
}


04-树5 Root of AVL Tree   (25分)


An AVL tree is a self-balancing binary search tree. In an AVL tree, the heights of the two child subtrees of any node differ by at most one; if at any time they differ by more than one, rebalancing is done to restore this property. Figures 1-4 illustrate the rotation rules.

Now given a sequence of insertions, you are supposed to tell the root of the resulting AVL tree.

Input Specification:

Each input file contains one test case. For each case, the first line contains a positive integer NNN (≤20\le 2020) which is the total number of keys to be inserted. Then NNN distinct 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, print the root of the resulting AVL tree in one line.

Sample Input 1:

5
88 70 61 96 120

Sample Output 1:

70

Sample Input 2:

7
88 70 61 96 120 90 65

Sample Output 2:

88


//有bug 
#include 
#include 
#define ElementType int

typedef struct Node * Tree;
struct Node{
	ElementType Element;
	Tree Left;
	Tree Right;
	int Height;
};

Tree BuildTree(int);
Tree Insert(Tree, int);
Tree SingleLeftRotation(Tree);
Tree SingleRightRotation(Tree);
Tree DoubleLeftRightRotation(Tree);
Tree DoubleRightLeftRotation(Tree);
void PrintRoot(Tree);
int Max(int, int);
int GetHeight(Tree);

int main()
{
	int N;
	Tree AVLTree;
	
	scanf("%d", &N);
	AVLTree = BuildTree(N);
	PrintRoot(AVLTree);
	
	return 	0;
}

Tree BuildTree(int N)
{
	int i, data;
	Tree T;
	
	for(i = 0; i < N; i++){
		scanf("%d", &data);
		T = Insert(T, data);
	}	

	return T;
}

//将data放入AVL树种,并返回调整后的AVL树 
Tree Insert(Tree T, int data)
{
	//创建一个新的结点 
	if(!T){
		T = (Tree)malloc(sizeof(struct Node));
		T->Element = data;
		T->Left = NULL;
		T->Right = NULL;
		T->Height = 0;
	}
	// 插入T的左子树 
	else if(data < T->Element){
		T->Left = Insert(T->Left, data);
		if(GetHeight(T->Left) - GetHeight(T->Right) == 2){
			if(data < T->Left->Element)
				T = SingleLeftRotation(T);
			else
				T = DoubleLeftRightRotation(T);	
		}
	}
	//插入T的右子树 
	else if(data > T->Element){
		T->Right = Insert(T->Right, data);
		if(GetHeight(T->Left) - GetHeight(T->Right) == -2){
			if(data > T->Right->Element)
				T = SingleRightRotation(T);
			else
				T = DoubleRightLeftRotation(T);	
		}
	}	
	//更新树高 
	T->Height = Max(GetHeight(T->Left), GetHeight(T->Right)) + 1;
	
	return T;
}

//LL LR RR Rl旋转 画图辅助看 很好理解的 
Tree SingleLeftRotation(Tree A)
{
	Tree B = A->Left;
	A->Left = B->Right;
	B->Right = A;
	A->Height = Max(GetHeight(A->Left), GetHeight(A->Right)) + 1;
	B->Height = Max(GetHeight(B->Left), A->Height) +1;
	
	return B;
}

Tree SingleRightRotation(Tree A)
{
	Tree B = A->Right;
	A->Right = B->Left;
	B->Left = A;
	A->Height = Max(GetHeight(A->Left), GetHeight(A->Right)) + 1;
	B->Height = Max(A->Height, GetHeight(B->Right)) + 1;
	
	return B;
}

Tree DoubleLeftRightRotation(Tree A)
{
	A->Left = SingleRightRotation(A->Left);
	return SingleLeftRotation(A);
}

Tree DoubleRightLeftRotation(Tree A)
{
	A->Right = SingleLeftRotation(A->Right);
	return SingleRightRotation(A);
}

void PrintRoot(Tree T)
{
	printf("%d", T->Element);
}

//比较函数 
int Max(int a, int b)
{
	return a >= b ? a : b;
}

//树高函数,当为空结点时候,树高-1 
int GetHeight(Tree T)
{
	if(T == NULL)
		return -1;
	else
		return T->Height;
}



你可能感兴趣的:(数据结构,MOOC-陈越,何钦铭)