是否同一棵二叉搜索树

  • 题目描述

  • 题目思路

1 第一种思路是比较容易想到的,就是直接根据输入的数据建立二叉搜索树,然后像判断两棵树是否同构那样,先判断根节点是否相同,然后再递归的判断左子树,右子树。
2 第二种思路是不建树,直接根据输入的序列使用递归的思想去解决。
3 第三种思路是建一棵树,再判断其他序列是否与该树一致。

  • 第三种思路的C语言实现
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>

struct TreeNode
{
	int Data;
	struct TreeNode* Left;
	struct TreeNode* Right;
	bool flag;
};

struct TreeNode* NewNode(int V)
{
	struct TreeNode* T = (struct TreeNode*)malloc(sizeof(struct TreeNode));
	T->Data = V;
	T->Left = T->Right = NULL;
	T->flag = false;
	return T;
}

struct TreeNode* Insert(struct TreeNode* T,int V)
{
	if (!T)  //若原树为空 生成并返回一个节点的二叉搜索树
	{
		T = NewNode(V);
	}
	else
	{
		if (V < T->Data)
		{
			//递归插入到左子树
			T->Left = Insert(T->Left, V);
		}
		else
		{
			//递归插入到右子树
			T->Right = Insert(T->Right,V);
		}
	}
	return T;
}

struct TreeNode* MakeTree(int N)
{
	struct TreeNode* T;
	int i, V;
	scanf("%d",&V);
	T = NewNode(V);
	for (i = 1; i < N; i++)
	{
		scanf("%d", &V);
		T = Insert(T,V);
	}

	return T;
}

int Check(struct TreeNode* T,int V)
{
	if (T->flag)  //该节点没有被访问过
	{
		if (V < T->Data)
		{
			return Check(T->Left, V);
		}
		else if (V > T->Data)
		{
			return Check(T->Right,V);
		}
		else
		{
			return 0;
		}
	}
	else 
	{
		if (V == T->Data)
		{
			//在树中标记该节点已经被访问过
			T->flag = true;
			return 1;
		}
		else
		{
			return 0;
		}
	}
}

int Judge(struct TreeNode* T,int N)
{
	int i, V;
	//flag = false表示目前还一致 true代表已经不一致了
	bool flag = false;

	scanf("%d",&V);
	
	if (V != T->Data)
	{
		flag = true;
	}
	else
	{
		T->flag = true;
	}

	for (i = 1;i < N;i++)
	{
		scanf("%d",&V);
		if ( !flag && ( !Check(T,V) ) )
		{
			flag = true;
		}
	}

	if(flag)
	{
		return 0;
	}
	else
	{
		return 1;
	}
}

void Reset(struct TreeNode* T)
{
	if (T->Left)
	{
		Reset(T->Left);
	}
	if (T->Right)
	{
		Reset(T->Right);
	}

	T->flag = 0;
}

void FreeTree(struct TreeNode* T)
{
	if (T->Left)
	{
		FreeTree(T->Left);
	}
	if (T->Right)
	{
		FreeTree(T->Right);
	}

	free(T);

}

int main()
{
	struct TreeNode* T;
	int L;
	int N;
	int i = 0;
	
	
	scanf("%d", &N);
	while (N != 0)
	{
		scanf("%d",&L);  //L是待检查的序列个数
		T = MakeTree(N);  //建树
		for (i = 0;i < L;i++)
		{
			if (Judge(T,N))
			{
				printf("Yes\n");
			}
			else
			{
				printf("No\n");
			}
			Reset(T);
		}
		FreeTree(T);
		scanf("%d", &N);
	}

	// system("pause");
	return 0;
}
posted @ 2019-08-30 09:25  尚修能的技术博客  阅读(337)  评论(0编辑  收藏  举报