Whether [pta7-4] is the same binary search tree

Recently, I was listening to the algorithm and data structure of Zhejiang University. I made a program following the video and put it here to record the learning process

Title:
Given an insertion sequence, a binary search tree can be uniquely determined. However, a given binary search tree can be obtained by many different insertion sequences. For example, insert the binary search tree which is initially empty according to the sequence {2, 1, 3} and {2, 3, 1} respectively, and get the same result. So for all kinds of insertion sequences, you need to judge whether they can generate the same binary search tree.

Input format:
The input contains several sets of test data. The first row of each group of data gives two positive integers N (≤ 10) and l, which are the number of inserted elements and the number of sequences to be checked. Line 2 shows N positive integers separated by spaces as the initial insertion sequence. Finally, L lines, each line gives N inserted elements, belonging to l sequences to be checked.

For simplicity, we guarantee that each insertion sequence is a permutation of 1 to N. When N is read as 0, mark the end of input. Do not process this set of data.

Output format:
For each set of sequences to be checked, if the binary search tree generated by it is the same as that generated by the corresponding initial sequence, output "Yes", otherwise output "No".

Input example:
4 2
3 1 4 2
3 4 1 2
3 2 4 1
2 1
2 1
1 2
0

Output example:
Yes
No
No

First, we need to solve several problems:

  1. Receive input part: binary search tree representation and tree building.
  2. Processing part: judge whether it is the same tree
  3. output

Part I (receiving input)

A binary tree is represented by a traditional structure:

/*Representation of binary tree*/
 struct TreeNode  
{
	int data;
	struct TreeNode * left;
	struct TreeNode* right;
	int flag; //This field should be used in subsequent judgment (wonderful, learned)
};
typedef struct TreeNode* Tree;
Tree T;  

Tree building is divided into three functions (I think the process from scratch here is quite abstract)
1. Create a node to wrap the read data into the NewNode function
2. Take the first built node as the root node, and the newly generated node and root node establish the logic through the Insert function (the subtree is hung on the binary tree)
3. Functions implemented by maketree function:
Establish the first root node and integrate the functions of the two functions into a large function.
(I don't know how to describe it)

Tree MakeTree(int n)
{
	int i, v;
	/*First, build the node of the first number*/
	scanf("%d", &v);
	T = NewNode(v);
	/*Then connect the remaining n-1 nodes*/
	for (i = 1; i < n; i++)
	{
		scanf("%d", &v);
		T = Insert(T, v);
	}
	return T;	
}

NewNode function:

/*Wrap data into a node*/
Tree NewNode(int v)
{
	T = (Tree)malloc(sizeof(struct TreeNode));
	T->data = v;
	T->flag = 0;
	T->left = NULL;
	T->right = NULL;
	return T;
}

Insert insert function –

Tree Insert(Tree T, int v)
{
	if (!T)
	{
		/*Create a root node in an empty search tree (a subtree is also an empty search tree)*/
		T = NewNode(v);
	}
	else
	{
		if (v > T->data)
		{
			T->right =Insert(T->right, v);
		}
		else
		{
			T ->left =Insert(T->left, v);
		}
	}
	return T;
}

The second part

After reading the data, we begin to process - to determine whether the two trees are the same:
According to the video, there are three methods:
1. Build two trees to judge the structure of the tree (easy to realize)
2. Do not build tree, judge directly according to sequence
3. Build a tree, another sequence to compare and tree comparison
He Lao's idea is as follows: after the tree is built, search in the tree one by one from the sequence to be compared, and set 1 for the flag field of the node on the tree found along the way. When searching for a certain number in the sequence on the tree, it is found that the flag field of a node on the tree along the way is not 1, which means that the node has not passed before the previous number is found The structure of this sequence is different from that of the tree
The sequence of trees is 3, 1, 4, 2.
The comparison sequence was: 3, 4, 1, 2 and 3, 2, 4, 1




Similarly, for the second comparison sequence, the order of marks on the tree is 3 - 2 - 1
When looking for element 2, it will be found that the node where 1 is on the tree is not marked as 1, and it is judged that it is not the same tree.

/*judge*/
int JudgeTree(Tree T, int n)
{
	int i = 0, v, flag = 0;
	scanf("%d", &v);
	/*Determine root node*/
	if (v != T->data)
		flag = 1;
	else
		T->flag = 1;
	/*Notice here is the number of n-1, i starts from 1 */
	for (i = 1; i < n; i++)
	{
		scanf("%d", &v);
		/*!flag If it is 0, it means flag=1. You don't need to call the check function, just read in*/
		if ((check(T, v) != 1) && (!flag))
			flag = 1;			
	}
	if(flag)
	return 0;
	else 
	return 1;

}

[note]: when reading the comparison sequence, there are N numbers in the buffer
If you exit without finishing reading, the number left in the buffer will become the number to be read next time, which will cause the program to fail, which is why the flag is set
When you find different structures, you can't directly end the function. Continue reading!

The basic idea of check function is the basic operation of binary search tree search

int check(Tree T, int v)
{
	if (T->flag)      //Those marked as 1 can continue to search
	{
		if (v > T->data)
		{
			check(T->right, v);
		}
		else if (v < T->data)
			check(T->left, v);
		else return 0;
	}
	else   //If not, judge whether it is the element to be found first. 
	{
		if (v == T->data)
		{
			T->flag = 1;
			return 1;
		}
		else return 0;
	}
}

Part three: output

There is nothing to say.
The remaining processing functions are:
1. When reading and comparing the next set of trees and comparison sequences, reset the flag field of the tree node to 0
2. After the end of the procedure, release the applied space (destruction of binary tree)

/*Reset flag domain*/
void Reset(Tree T)
{
	if (T->left)
		Reset(T->left);
	if (T->right)
		Reset(T->right);
	T->flag = 0;
}
/*Destruction of binary tree*/
void FreeTree(Tree T)
{
	if (T->left)
		FreeTree(T->left);
	if (T->right)
		FreeTree(T->right);
		free(T);
}

The main functions are as follows:

/*Please read in according to the topic requirements*/
int main()
{
	int N, L ,i = 0;
	scanf("%d", &N);
	while (N)
	{
		scanf("%d", &L);
		T = MakeTree(N);
		for (i = 0; i < L; i++)
		{
			if (JudgeTree(T, N))
				printf("Yes\n");
			else
				printf("No\n");
			Reset(T);			
		}
		FreeTree(T);
		scanf("%d", &N);
	}
}

The complete procedure is as follows:

#include <stdio.h>
#include <stdlib.h>
struct TreeNode  
{
	int data;
	struct TreeNode * left;
	struct TreeNode* right;
	int flag;
};
typedef struct TreeNode* Tree;
Tree T;
Tree NewNode(int v)
{
	T = (Tree)malloc(sizeof(struct TreeNode));
	T->data = v;
	T->flag = 0;
	T->left = NULL;
	T->right = NULL;
	return T;
}
Tree Insert(Tree T, int v)
{
	if (!T)
	{
		/*Create a root node in an empty search tree (a subtree is also an empty search tree)*/
		T = NewNode(v);
	}
	else
	{
		if (v > T->data)
		{
			T->right =Insert(T->right, v);
		}
		else
		{
			T ->left =Insert(T->left, v);
		}
	}
	return T;
}
Tree MakeTree(int n)
{
	int i, v;
	/*First, build the node of the first number*/
	scanf("%d", &v);
	T = NewNode(v);
	/*Then connect the remaining n-1 nodes*/
	for (i = 1; i < n; i++)
	{
		scanf("%d", &v);
		T = Insert(T, v);
	}
	return T;	
}
int check(Tree T, int v)
{
	if (T->flag)
	{
		if (v > T->data)
		{
			check(T->right, v);
		}
		else if (v < T->data)
			check(T->left, v);
		else return 0;
	}
	else
	{
		if (v == T->data)
		{
			T->flag = 1;
			return 1;
		}
		else return 0;
	}
}
int JudgeTree(Tree T, int n)
{
	int i = 0, v, flag = 0;
	scanf("%d", &v);
	/*Determine root node*/
	if (v != T->data)
		flag = 1;
	else
		T->flag = 1;
	/*Notice here is the number of n-1, i starts from 1 */
	for (i = 1; i < n; i++)
	{
		scanf("%d", &v);
		/*!flag If it is 0, it means that flag=1. You don't need to check to read it in*/
		if ((check(T, v) != 1) && (!flag))
			flag = 1;			
	}
	if(flag)
	return 0;
	else 
	return 1;

}
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);
}
int main()
{
	int N, L ,i = 0;
	scanf("%d", &N);
	while (N)
	{
		scanf("%d", &L);
		T = MakeTree(N);
		for (i = 0; i < L; i++)
		{
			if (JudgeTree(T, N))
				printf("Yes\n");
			else
				printf("No\n");
			Reset(T);			
		}
		FreeTree(T);
		scanf("%d", &N);
	}
}
Published 7 original articles, won praise 0, visited 255
Private letter follow

Posted on Fri, 07 Feb 2020 05:12:26 -0500 by alex57