Binary tree OJ topic collection (single value, symmetry, balance, construction plus traversal)

Table of contents

Foreword:

One: Single-valued binary tree

Two: Binary tree traversal

core point

(1) Preamble

(2) Inorder

(3) Subsequent sequence

Three: Determine whether the two trees are the same

Four: Determine whether the binary tree is symmetrical

Five: Determine whether a tree is a subtree of another tree

Six: balanced binary tree

Seven: Construction and traversal of binary tree


Foreword:

This part is suitable for students who have already mastered the basics of binary trees (traversing, finding the number of nodes, etc.) .

Students who are not clear can read the previous issue first:

https://blog.csdn.net/2301_76269963/article/details/130231257?spm=1001.2014.3001.5502

One: Single-valued binary tree

Link to the topic: https://leetcode.cn/problems/univalued-binary-tree/submissions/

Topic requirements:

Basic idea:

(1) First judge whether the value of the root node is the same as that of the left and right subtrees , and return false if they are different. ( Note that if the left and right subtrees are empty, no judgment is required )

(2) Otherwise, recursively judge whether its left and right subtrees are single-valued binary trees . ( An empty tree counts as a single-valued binary tree )

(3) If there is no different node value up to the leaf node, then return true , indicating that the tree is a single-valued binary tree.

(The left subtree and the right subtree must both be single-value trees)

(This topic is relatively simple and can be achieved without using recursion, but an auxiliary stack needs to be established. Just traverse all nodes and judge in turn. If there is a difference, return false, and if there is no difference after traversing, return true)

code:

bool isUnivalTree(struct TreeNode* root)
{
    if(root == NULL)
    {
        return true;
    }

    if(root->left!=NULL && root->left->val != root->val)
    {
        return false;
    }

    if(root->right!=NULL && root->right->val != root->val)
    {
        return false;
    }

    return isUnivalTree(root->left) && isUnivalTree(root->right);

}

Illustration:

Two: Binary tree traversal

core point

(1) We know that the formal parameter is only a temporary copy of the actual parameter when the function is called . If we directly call by value, there is no way to directly establish a connection with that variable.

(2) If we want the function to always use a variable no matter how deep the recursion is, we should call by reference .

(1) Preamble

Link to the topic: https://leetcode.cn/problems/binary-tree-preorder-traversal/submissions/

Topic requirements:

Ideas:

①Different from our previous printing, this traversal is to store the node data in the array

②Find the number of nodes first (I talked about it once before), and open up space according to the number of nodes

③ Store the data first, then recursively go to the left subtree, and then recursively go to the right subtree. Every time the storage is completed, add 1 to (*i) (add 1 to the body)

④ Remember to assign the number of array elements to (*returnSize) , and tell the number of elements so that others can test

code:

//求树的节点数
int BinaryTreeSize(struct TreeNode* root)
{
	return root == NULL ? 0 :
		BinaryTreeSize(root->left) + BinaryTreeSize(root->right) + 1;
}

void _preorderTraversal(struct TreeNode* root,int* a,int* i)
{
    if(root == NULL)
    {
        return;
    }
    //赋值
    a[*i] = root->val;
    *i+=1;
    //左子树
    _preorderTraversal(root->left,a,i);
    //右子树
    _preorderTraversal(root->right,a,i);
}

int* preorderTraversal(struct TreeNode* root, int* returnSize)
{
    //申请空间存储数据
    int size=BinaryTreeSize(root);
    int* a=(int*)malloc(sizeof(int)*size);

    //遍历存储数据(利用子函数)
    int i=0;
    _preorderTraversal(root,a,&i);

    //返回
    *returnSize = size;
    return a;
}

(2) Inorder

Link to the topic: https://leetcode.cn/problems/binary-tree-inorder-traversal/submissions/

Topic requirements:

Idea: It is basically the same as the preorder, but the order of storage is changed

code:

//求树的节点数
int BinaryTreeSize(struct TreeNode* root)
{
	return root == NULL ? 0 :
		BinaryTreeSize(root->left) + BinaryTreeSize(root->right) + 1;
}

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

int* inorderTraversal(struct TreeNode* root, int* returnSize)
{
    //申请空间存储数据
    int size = BinaryTreeSize(root);
    int* a = (int*)malloc(sizeof(int)*size);
    
    //调用子函数存储
    int i=0;
    _inorderTraversal(root,a,&i);

    //返回
    *returnSize = size;
    return a;
}

(3) Subsequent sequence

Link to the topic: https://leetcode.cn/problems/binary-tree-postorder-traversal/submissions/

Topic requirements:

Idea: It is basically the same as the preorder, but the order of storage is changed

code:

//求树的节点数
int BinaryTreeSize(struct TreeNode* root)
{
	return root == NULL ? 0 :
		BinaryTreeSize(root->left) + BinaryTreeSize(root->right) + 1;
}

void _postorderTraversal(struct TreeNode* root,int* a,int* i)
{
    if(root == NULL)
    {
        return;
    }
    //左子树
    _postorderTraversal(root->left,a,i);
    //右子树
    _postorderTraversal(root->right,a,i);
    //存储
    a[*i] = root->val;
    *i += 1;
}

int* postorderTraversal(struct TreeNode* root, int* returnSize)
{
    //申请空间存储
    int size = BinaryTreeSize(root);
    int* a = (int*)malloc(sizeof(int)*size);

    //调用子函数遍历存储
    int i=0;
    _postorderTraversal(root,a,&i);

    //返回
    *returnSize = size;
    return a;
}

Three: Determine whether the two trees are the same

Link to the topic: https://leetcode.cn/problems/same-tree/submissions/

Topic requirements:

Basic idea:

(1) First judge the node address , if both sides are empty, return true, if one side is empty and the other is not empty, return false

(2) Then judge whether the root data is the same , and return false if it is different

(3) Otherwise, recursively determine whether the left subtree and the right subtree are the same

(4) Except for the root, the left and right subtrees are the same, and the two trees are the same

code:

bool isSameTree(struct TreeNode* p, struct TreeNode* q)
{
    if(p == NULL && p==q)
    {
        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);
}

Four: Determine whether the binary tree is symmetrical

Link to the topic: https://leetcode.cn/problems/symmetric-tree/submissions/

Topic requirements:

Basic idea:

(1) It is very similar to judging whether the two trees are the same as before, which is equivalent to treating the left and right subtrees as 1 tree and 2 tree

(2) First judge the node address , if both sides are empty, return true, if one side is empty and the other is not empty, return false

(3) First compare whether the roots are the same, if they are different, return false

(4) The roots are the same, recursively judge whether the left subtree of tree 1 is the same as the right subtree of tree 2, whether the right subtree of tree 1 is the same as the left subtree of tree 2

(5) The leaf nodes are still the same, indicating that the tree is symmetrical

code:

bool CheckSymmetry(struct TreeNode* left,struct TreeNode* right)
{
    //如果都为空,对称
    if(left == NULL && left == right)
    {
        return true;
    }
    //一方为空一方不为,不对称
    if(left == NULL || right == NULL)
    {
        return false;
    }

    if(left->val != right->val)
    {
        return false;
    }

    return CheckSymmetry(left->left,right->right) 
        && CheckSymmetry(left->right,right->left);
}


bool isSymmetric(struct TreeNode* root)
{
    //利用子函数判断是否对称
    return CheckSymmetry(root->left,root->right);
}

Five: Determine whether a tree is a subtree of another tree

Link to the topic: https://leetcode.cn/problems/subtree-of-another-tree/

Topic requirements:

Basic idea:

(1) The general idea is to compare each subtree of the mother tree with subRoot in turn

have the same return true, otherwise return false

(2) If the parent tree is empty, return false

(3) Using the previous function to judge whether the two trees are the same, we first judge whether the mother tree and subRoot are the same

(4) Return true if they are the same, if they are different, recursively go to the left subtree and right subtree of the mother tree

(5) As long as one of the left and right subtrees is the same, it is true

code:

//判断两颗树是否相同
bool isSameTree(struct TreeNode* p, struct TreeNode* q)
{
    if(p == NULL && p==q)
    {
        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);
}

Illustration:


Six: balanced binary tree

Link to the topic: https://leetcode.cn/problems/balanced-binary-tree/

Topic requirements:

 Basic idea:

(1) Return true if the node is empty (the empty tree is also a balanced binary tree)

(2) Use the function (mentioned before) to calculate the height difference between the left and right subtrees of the current node

(3) If the height difference does not exceed 1, recursively determine whether its left and right subtrees are balanced binary trees

(4) If the height difference between the left and right subtrees of any node is greater than 1 , the tree is not a balanced binary tree

code:

//求树高度
int BinaryTreeDepth(struct TreeNode* root)
{
	if (root == NULL)
	{
		return 0;
	}

	if (root->left == NULL && root->right == NULL)
	{
		return 1;
	}

	return fmax(BinaryTreeDepth(root->left), BinaryTreeDepth(root->right)) + 1;
}

bool isBalanced(struct TreeNode* root)
{
    if(root == NULL)
        return true;

    int leftDepth = BinaryTreeDepth(root->left);
    int rightDepth = BinaryTreeDepth(root->right);
    
    return abs(leftDepth-rightDepth)>1?false:
    isBalanced(root->left)&&isBalanced(root->right);
}

Seven: Construction and traversal of binary tree

Topic link: https://www.nowcoder.com/practice/4b91205483694f449f94c179883c1fef?tpId=0&difficulty=&judgeStatus=&tags=&title=%E4%BA%8C%E5%8F%89%E6%A0%91&sourceUrl=&gioEnter=menu

Topic requirements:

Basic idea:

(1) Build a tree based on the input string (recursive)

①The order of creation is first the left subtree and then the right subtree

②In order to ensure that the same variable is used in the recursive process, we pass the address of the subscript

If the character is '#' or '\0' (the string goes to empty), the node address assignment is empty

Return the address of the root node of the created tree

Illustration:

 

(2) Perform in-order traversal (I said it before, so I won’t go into details)

code:

#include <stdio.h>
#include <stdlib.h>

typedef char BTDataType;

typedef struct BinaryTreeNode
{
	//存储左孩子的地址
	struct BinaryTreeNode* left;
	//存储右孩子的地址
	struct BinaryTreeNode* right;
	BTDataType data;
}BTNode;

BTNode* maketree(char*arr,int* i)
{
    if(arr[*i]=='#'||arr[*i]=='\0')
    {
        return NULL;
    }
    BTNode* newnode = (BTNode*)malloc(sizeof(BTNode));
    newnode->data = arr[(*i)++];
     
    newnode->left = maketree(arr,i);
    //这里加1是因为字符为'#'时候直接返回了空
    //我们要走到下一个字符就要进行自加
    (*i)++;
    newnode->right = maketree(arr,i);
    return newnode;
}

//中序遍历
void InOrder(BTNode* root)
{
    if(root == NULL)
    {
        return;
    }
	
	//左树
	InOrder(root->left);
	//打印
	printf("%c ", root->data);
	//右树
	InOrder(root->right);
}

int main() 
{
    //字符串长度不超过100
    char str[100]= {0};

    //可能有多组输入   
    while(scanf("%s",str) != EOF)
    {
        //建树
        int i = 0;
        BTNode* root = maketree(str,&i);

        //遍历
        InOrder(root);
    }

    return 0;
}

Guess you like

Origin blog.csdn.net/2301_76269963/article/details/130446655