[Data structure] Binary tree oj question

Before dealing with the oj problem, we need to deal with the remaining issues first

Find the node x in the binary tree

BTNode* BinaryTreeFind(BTNode* root, int x)
{
    
    
	if (root == NULL)
		return NULL;
	if (root->data == x)
	
		return root;
	BTNode* ret1 = BinaryTreeFind(root->left, x);
	BTNode* ret2 = BinaryTreeFind(root->right, x);
	if (ret1)
	    return ret1;
	if (ret2)
		return ret2;
	return NULL;

}

Recursive graph
Insert image description here
Use ret1 and ret2 pointers to record the return values ​​of the left subtree and right subtree respectively. If found in the left subtree, an address will be returned. Use ret1 to record the pointer. , so that ret1 is not empty. At this time, it will recursively return to the previous layer. In the previous layer, enter the if (ret1) conditional judgment statement, and return the address of node x to the previous layer, all the way to the root node of the entire tree. .The same applies if ret2 is not empty.
Insert image description here

#Single-valued binary tree

Problem description
Insert image description here
Yogo

bool isUnivalTree(struct TreeNode* root) {
    
    
    if(root==NULL)
    return true;
    if(root->left&&root->left->val!=root->val)
    return false;
    if(root->right&&root->right->val!=root->val)
    return false;
    return isUnivalTree(root->left)&&isUnivalTree(root->right);  

    
}

recursive graph
Insert image description here

When the root and the left and right subtrees are equal, the left and right subtrees will be recursed all the time. The left and right subtrees will be the root nodes respectively, and judge whether they are equal to their left and right subtrees. When the recursion reaches the left side of the leaf node, When the tree is a right tree, both will return 1. The left subtree of the middle right subtree is empty, and the right subtree is 1. If the left subtree is empty, 1 will be returned. The right subtree is the root, and its left and right subtrees are empty. If the subtree is empty, 1 is returned. The left and right subtrees of the root node of the tree return two 1s and get 1, so that the result can be determined. See the recursion diagram above for details.
#< /span> Code Problem DescriptionSymmetric Binary Tree

Insert image description here

  bool _isSymmetric(struct TreeNode* leftroot,struct TreeNode* rightroot) 
 {
    
    if(leftroot==NULL&&rightroot==NULL)
   return true;
   if(leftroot==NULL||rightroot==NULL)
   return false;
   if(leftroot->val!=rightroot->val)
   return false;
   return _isSymmetric(leftroot->left,rightroot->right)&&_isSymmetric(leftroot->right,rightroot->left); 
}
bool isSymmetric(struct TreeNode* root) {
    
    
return  _isSymmetric(root->left,root->right);    
} 

Insert image description here
Insert image description here

#Preorder traversal of binary tree
Insert image description here
Code

 int BinaryTreeSize(struct TreeNode* root)
{
    
    

	return root == NULL ? 0 : BinaryTreeSize(root->left) + BinaryTreeSize(root->right) + 1;




}
void aapreorderTraversal(struct TreeNode*root,int*a,int i)
{
    
    if(root==NULL)
  return ;
  a[i++]=root->val;
  aapreorderTraversal(root->left,a,i);
  aapreorderTraversal(root->right,a,i);
}


int* preorderTraversal(struct TreeNode* root, int* returnSize) {
    
    
    *returnSize=BinaryTreeSize(root);
    int*a=(int*)malloc(*returnSize*sizeof(int));
    int i=0;
    aapreorderTraversal(root,a,i);
    return a;
}

Note that there are some problems with the above code. Let me explain the code first, and then solve the above problems.
We have written preorder traversal before, but the difference in this question is that we need to The results of the sequential traversal are put into an array and the array is returned. The first problem we solve is the number of binary tree nodes. Because we want to create arrays of the same size, here we need to use the function to find the number of binary tree nodes. The number of returned nodes is received using returnsize,
Insert image description here
and the array needs to be created by yourself,
Insert image description here
if used in this function In the case of pre-order traversal, malloc will be used for each recursion, so we use another function to perform recursive pre-order traversal,
Insert image description here
Insert image description here
The parameters passed to the recursive pre-order traversal function respectively include the address of the root of the binary tree to be traversed. , the first address of the array from malloc, and the subscript of the array. The specific pre-order traversal is explained in detail in the article on binary trees. Now let’s talk about the existing problems
Insert image description here
Insert image description here
When the entered data is In the stack frame of 2, i is still 1 at this time, which will overwrite the stack frame with data of 1 and write a[1]=1;
The current a[1]=2; because in It is already known that there are three nodes in the number of binary tree nodes, so the random value in
(a+2) will be printed out. The specific solution is to pass the subscript address and use a pointer Receive.
code

 int BinaryTreeSize(struct TreeNode* root)
{
    
    

	return root == NULL ? 0 : BinaryTreeSize(root->left) + BinaryTreeSize(root->right) + 1;




}
void aapreorderTraversal(struct TreeNode*root,int*a,int* pi)
{
    
    if(root==NULL)
  return ;
  a[(*pi)++]=root->val;
  aapreorderTraversal(root->left,a,pi);
  aapreorderTraversal(root->right,a,pi);
}


int* preorderTraversal(struct TreeNode* root, int* returnSize) {
    
    
    *returnSize=BinaryTreeSize(root);
    int*a=(int*)malloc(*returnSize*sizeof(int));
    int i=0;
    aapreorderTraversal(root,a,&i);
    return a;
}

#In-order traversal
#Post-order traversal
This Both of them only need to modify the position
Insert image description here
#Another subtree
Question description
Insert image description here
Code implementation

bool isSameTree(struct TreeNode* p, struct TreeNode* q) {
    
    
if(p==NULL&&q==NULL)
{
    
    return true;}
if(p==NULL||q==NULL)
{
    
    return false;}
if(p->val!=q->val)
return false;
return isSameTree(p->left, q->left)&&isSameTree(p->right, q->right);
}
bool isSubtree(struct TreeNode* root, struct TreeNode* subRoot){
    
    
if(root==NULL)
return false;
if(isSameTree(root, subRoot))
return true;
return isSubtree(root->left, subRoot)||isSubtree(root->right, subRoot);
}

The same tree function is used here

bool isSameTree(struct TreeNode* p, struct TreeNode* q) {
    
    
if(p==NULL&&q==NULL)
{
    
    return true;}
if(p==NULL||q==NULL)
{
    
    return false;}
if(p->val!=q->val)
return false;
return isSameTree(p->left, q->left)&&isSameTree(p->right, q->right);
}

Recursive binary trees take the current node as the root and compare it with subRoot. If they are different, recurse the left and right subtrees. If there are subtrees in the left and right subtrees that are the same as the tree with subroot as the root, return 1. When the roots are the same , the function isSameTree(struct TreeNode* p, struct TreeNode* q) will be called to compare whether the left subtree and the right subtree are the same. If root==NULL at the beginning, subroot will definitely not return false for the subtree. It is recommended that you draw a recursion diagram. It will be much easier to understand.

Guess you like

Origin blog.csdn.net/yyqzjw/article/details/134624021