PTA 是否同一棵二叉搜索树 思路分析及代码解析

一、前导

1. 需要掌握的知识

二叉搜索树基本概念、建树

2. 题目信息

题目来源:PTA / 拼题A
题目地址:https://pintia.cn/problem-sets/15/problems/712

二、解题思路分析

1. 题意理解

  1. 输入数据
4 2		\\4表示树的节点个数,2表示待检查的序列个数
3 1 4 2		\\初始序列,待检查的序列以此为标准
3 4 1 2		\\待检查的序列
3 2 4 1		\\待检查的序列
2 1		\\同 4 2
2 1
1 2	
0		\\0表示程序结束
  1. 输出数据
Yes		\\对应待检查序列的检测结果
No
No
  1. 题意
    不同的输入序列可能生成相同的二叉搜索树,若序列产生的二叉搜索树相同,输出Yes,否则输出No

2. 思路分析(重点)

  1. 根据二叉搜索树的特点,先建树再比对

三、具体实现

1. 弯路和bug

  1. 由于粗心、编码能力不强,导致犯了各种中二晚期错误。比如:在for()语句后面加了**;** 导致建树一直异常

2. 代码框架(重点)

2.1 采用的数据结构

使用结构体数组,命名时做到见名知意

typedef struct BinarySearchTree *PBST;
struct BinarySearchTree
{
	int value;
	PBST left;
	PBST right;
};

2.2 程序主体框架

               程序伪码描述
int main()
{	
	1.根据序列创建树
	2.比较树
}

2.3 各分支函数

  1. PBST Add(PBST Tree,int input_value); 将节点加入树中,被CreateTree()调用。分为树空 和 树非空;树非空时,按搜索树左小右大的原则进行判定。属于建树基本功,需要熟练。
PBST Add(PBST Tree,int input_value)
{
	if(!Tree)
	{
		Tree=(PBST)malloc(sizeof(struct BinarySearchTree));
		Tree->value=input_value; 
		Tree->left=NULL; 
		Tree->right=NULL;
	}
	else
	{
		if( input_value < Tree->value)
			Tree->left=Add(Tree->left,input_value);
		else
			Tree->right=Add(Tree->right,input_value);
	}
	return Tree;
}
  1. PBST CreateTree(PBST Tree,int TreeNode); 通过Add()完成建树
PBST CreateTree(PBST Tree,int TreeNode)
{
	int input_value;
	for(int j=0;j<TreeNode;j++)
	{
		cin>>input_value; 
		Tree=Add(Tree,input_value);
	}	
	return Tree;	
} 
  1. bool Judge(PBST Tree1,PBST Tree2); 判定是否同一棵二叉搜索树,将所有场景考虑到就可以AC,此处锻炼自己逻辑思维能力
bool Judge(PBST T1,PBST T2)
{
	if(!T1 && !T2) return true; //1.树都为空
	if( (!T1 && T2) || (T1 && !T2)  ) return false; //2.树一棵空,一棵不空
	if(T1->value != T2->value) return false; //3.树根不同
	else //4.树根相同,仅需要判定左子树,右子树用递归解决
	{
		if(!T1->left && !T2->left) return Judge(T1->right,T2->right);//4.1左子树均为空,递归右子树
		if( (!T1->left && T2->left) || (T1->left && !T2->left) ) return false;	//4.2 左子树一棵空 一棵不空
		if(T1->left&&T2->left) return (Judge(T1->left,T2->left) && Judge(T1->right,T2->right));	//4.3 左子树不空,递归左右子树
	}	
}

3. 完整编码

#include <cstdlib>
#include <iostream>
using namespace std;

typedef struct BinarySearchTree *PBST;
struct BinarySearchTree
{
	int value;
	PBST left;
	PBST right;
};

PBST Add(PBST Tree,int input_value);
PBST CreateTree(PBST Tree,int TreeNode);
bool Judge(PBST Tree1,PBST Tree2);

int main()
{
	int TreeNode,CheckNumber; 
	bool result=false;
	PBST ReferTree=NULL,CompareTree=NULL;
	cin>>TreeNode>>CheckNumber;
	while(true)
	{
		ReferTree=CreateTree(ReferTree,TreeNode);	
		
		while(CheckNumber)
		{
			CompareTree=CreateTree(CompareTree,TreeNode);
			CheckNumber--;
			
			result=Judge(ReferTree,CompareTree);
			if(result) cout<<"Yes"<<endl;
			else cout<<"No"<<endl;
			
			CompareTree=NULL;
			result=false;
		}
		
		cin>>TreeNode;
		if(!TreeNode) return 0;
		cin>>CheckNumber;
		ReferTree=NULL;
	}
	return 0; 
}

PBST CreateTree(PBST Tree,int TreeNode)
{
	int input_value;
	for(int j=0;j<TreeNode;j++)
	{
		cin>>input_value; 
		Tree=Add(Tree,input_value);
	}	
	return Tree;	
} 

PBST Add(PBST Tree,int input_value)
{
	if(!Tree)
	{
		Tree=(PBST)malloc(sizeof(struct BinarySearchTree));
		Tree->value=input_value; 
		Tree->left=NULL; 
		Tree->right=NULL;
	}
	else
	{
		if( input_value < Tree->value)
			Tree->left=Add(Tree->left,input_value);
		else
			Tree->right=Add(Tree->right,input_value);
	}
	return Tree;
}

bool Judge(PBST T1,PBST T2)
{
	if(!T1 && !T2) return true;
	
	if( (!T1 && T2) || (T1 && !T2)  ) return false;
	
	if(T1->value != T2->value) return false;
	else //root is same,judge the left
	{
		if(!T1->left && !T2->left) return Judge(T1->right,T2->right);
		if( (!T1->left && T2->left) || (T1->left && !T2->left) ) return false;
		if(T1->left&&T2->left) return (Judge(T1->left,T2->left) && Judge(T1->right,T2->right));
	}	
}

2021.10.8
进步点:考虑了内存的释放 + 代码整体规划
缺点:忘记了复位参考树,Debug了好久 哭死…

#include <iostream>
using namespace std;

typedef struct Node* BST;
typedef int ElementType;

struct Node
{
	ElementType Value;
	BST Left;
	BST Right;
};

BST Insert(BST Tree, ElementType Value);
bool Judge(BST Tree01, BST Tree02);
void FreeMem(BST Tree);

int main()
{
	int N;	cin >> N;

	while (N)
	{
		int M; cin >> M;

		BST Tree01 = NULL;//fix bug
		
		int Value; 
		for (int i = 0; i < N; i++)
		{
			cin >> Value;
			Tree01 = Insert(Tree01, Value);
		}

		BST Tree02;
		while (M--)
		{
			Tree02 = NULL;
			for (int i = 0; i < N; i++)
			{
				cin >> Value;
				Tree02 = Insert(Tree02, Value);
			}

			bool Result = Judge(Tree01, Tree02);
			if (Result)
				cout << "Yes" << endl;
			else
				cout << "No" << endl;

			FreeMem(Tree02);
		}
		FreeMem(Tree01);
		cin >> N;
	}
	
	return 0;
}

void FreeMem(BST Tree)
{
	BST Left, Right;

	if (!Tree)
		return;

	if (Tree)
	{
		Left = Tree->Left;
		Right = Tree->Right;
		delete Tree;
		FreeMem(Left);
		FreeMem(Right);
	}
	return;
}

bool Judge(BST Tree01, BST Tree02)
{
	if (!Tree01 && !Tree02) //1.All Empty
		return true;

	if ((Tree01 && !Tree02) || (!Tree01 && Tree02)) //2. One Empty,the out
		return false;

	if (Tree01->Value != Tree02->Value)
		return false;
	else
		return  Judge(Tree01->Left,Tree02->Left) && Judge(Tree01->Right,Tree02->Right);

}

BST Insert(BST Tree, ElementType Value)
{
	if (!Tree)
	{
		Tree = new struct Node;
		Tree->Value = Value;
		Tree->Left = Tree->Right = NULL;
	}
	else
	{
		if (Value > Tree->Value)
			Tree->Right = Insert(Tree->Right, Value);
		else
			Tree->Left = Insert(Tree->Left, Value);
	}
	return Tree;
}

四、参考

1. 浙江大学 陈越、何钦铭老师主讲的数据结构

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值