Binary tree (below) + Leetcode daily question - "Data structure and algorithm", "Symmetric binary tree", "Subtree of another tree", "Binary tree's front, middle and back order traversal"

Hello everyone uu from CSDN, today Xiaoyalan’s content is still the daily question of binary tree and Leetcode, let’s enter the world of binary tree! ! !


 

 

This question needs to redefine a function. The function parameters need to have a left subtree and a right subtree. The function given in the question cannot solve the problem.

bool _isSymmetric(struct TreeNode* leftRoot,struct TreeNode* rightRoot)
{
    //左子树和右子树同时为空
    if(leftRoot==NULL&&rightRoot==NULL)
    {
        return true;
    }
    //一棵树为空,另一棵树不为空
    if((leftRoot==NULL&&rightRoot!=NULL)||
    (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);
}

 


 

 

 

Every node that is not empty can be considered as the root of a subtree 

//两棵树相同
bool isSameTree(struct TreeNode* p, struct TreeNode* q){
    //两个都为空
    if(p==NULL&&q==NULL)
    {
        return true;
    }
    //一个为空,另一个不为空
    if((p==NULL&&q!=NULL)||(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;
    }
    //root和subRoot相同
    if(isSameTree(root,subRoot))
    {
        return true;
    }
    //root的左子树与subRoot有相同或者root的右子树与subRoot有相同
    //满足其中一个条件即可,所以用||
    return isSubtree(root->left,subRoot)||
            isSubtree(root->right,subRoot);
}

 

 


 

 

Be careful when passing array subscripts in recursion! ! !

There is an array subscript in each stack frame! !

So you need to pass the address of the array subscript.

int TreeSize(struct TreeNode* root)
{
    return root==NULL?0:TreeSize(root->left)+TreeSize(root->right)+1;
}
//递归里面传数组下标要注意!!!
//每个栈帧里面都有一个i
void preorder(struct TreeNode* root,int* a,int* pi)
{
    if(root==NULL)
    {
        return;
    }
    a[(*pi)++]=root->val;
    preorder(root->left,a,pi);
    preorder(root->right,a,pi);
}
int* preorderTraversal(struct TreeNode* root, int* returnSize){
    //root是输入型参数,returnSize是返回型参数
    *returnSize=TreeSize(root);
    int* a=(int*)malloc(*returnSize*sizeof(int));
    int i=0;
    preorder(root,a,&i);
    return a;
}

 

 

Of course, there is another solution to this problem, which is to use i as a global variable, but special attention must be paid to this, and mistakes will occur if you are not careful

int TreeSize(struct TreeNode* root)

{

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

}

// Be careful when passing array subscripts in recursion! ! !

//There is an i in each stack frame

int i=0;

void preorder(struct TreeNode* root,int* a)

{

    if(root==NULL)

    {

        return;

    }

    a[i++]=root->val;

    preorder(root->left,a);

    preorder(root->right,a);

}

int* preorderTraversal(struct TreeNode* root, int* returnSize){

    //root is an input parameter, returnSize is a return parameter

    *returnSize=TreeSize(root);

    int* a=(int*)malloc(*returnSize*sizeof(int));

    i=0;

    preorder(root,a);

    return a;

}

 

int TreeSize(struct TreeNode* root)

{

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

}

void inorder(struct TreeNode* root,int* a,int* pi)

{

    if(root==NULL)

    {

        return;

    }

    inorder(root->left,a,pi);

    a[(*pi)++]=root->val;

    inorder(root->right,a,pi);

}

int* inorderTraversal(struct TreeNode* root, int* returnSize){

    //root is an input parameter, returnSize is a return parameter

    *returnSize=TreeSize(root);

    int* a=(int*)malloc(*returnSize*sizeof(int));

    int i=0;

    inorder(root,a,&i);

    return a;

}

 

 

int TreeSize(struct TreeNode* root)

{

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

}

void postorder(struct TreeNode* root,int* a,int* pi)

{

    if(root==NULL)

    {

        return;

    }

    postorder(root->left,a,pi);

    postorder(root->right,a,pi);

     a[(*pi)++]=root->val;

}

int* postorderTraversal(struct TreeNode* root, int* returnSize){

    //root is an input parameter, returnSize is a return parameter

    *returnSize=TreeSize(root);

    int* a=(int*)malloc(*returnSize*sizeof(int));

    int i=0;

    postorder(root,a,&i);

    return a;

}

 

 


sequence traversal

In addition to pre-order traversal, in-order traversal, and post-order traversal, level-order traversal of binary trees can also be performed. Assuming that the root node of the binary tree is at 1 layer, the layer order traversal is to start from the root node of the binary tree where it is located, first visit the root node of the first layer, then visit the nodes on the second layer from left to right, and then the third The nodes of the layer, and so on, the process of visiting the nodes of the tree layer by layer from top to bottom and from left to right is layer order traversal.

 

1 comes out with 2 and 4, 2 comes out with 3 and NULL, 4 comes out with 6 

The core of writing this code is to have a queue! ! !

Contents of Queue.h:

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<assert.h>
typedef struct BinaryTreeNode* QDataType;
// 链式结构:表示队列 
typedef struct QueueNode
{
	struct QueueNode* next;
	QDataType data;
}QueueNode;
// 队列的结构 
typedef struct Queue
{
	QueueNode* phead;//头指针
	QueueNode* ptail;//尾指针
	int size;
}Queue;
// 初始化队列
void QueueInit(Queue* pq);

// 销毁队列 
void QueueDestroy(Queue* pq);

// 队尾入队列 
void QueuePush(Queue* pq, QDataType x);

// 队头出队列 
void QueuePop(Queue* pq);

// 获取队列头部元素 
QDataType QueueFront(Queue* pq);

// 获取队列队尾元素 
QDataType QueueBack(Queue* pq);

// 获取队列中有效元素个数 
int QueueSize(Queue* pq);

// 检测队列是否为空
bool QueueEmpty(Queue* pq);

Contents of Queue.c:

#include"Queue.h"
// 初始化队列
void QueueInit(Queue* pq)
{
	assert(pq);
	pq->phead = NULL;
	pq->ptail = NULL;
	pq->size = 0;
}
// 销毁队列 
void QueueDestroy(Queue* pq)
{
	assert(pq);
	QueueNode* cur = pq->phead;
	while (cur != NULL)
	{
		QueueNode* next = cur->next;
		free(cur);
		cur = next;
	}
	pq->phead = pq->ptail = NULL;
	pq->size = 0;
}
// 队尾入队列 
void QueuePush(Queue* pq, QDataType x)
{
	assert(pq);
	QueueNode* newnode = (QueueNode*)malloc(sizeof(QueueNode));
	if (newnode == NULL)
	{
		perror("malloc fail");
		return;
	}
	newnode->data = x;
	newnode->next = NULL;
	//是空队列的情况
	if (pq->ptail == NULL)
	{
		assert(pq->phead == NULL);
		pq->phead = pq->ptail = newnode;
	}
	else
	{
		pq->ptail->next = newnode;
		pq->ptail = newnode;
	}
	pq->size++;
}
// 检测队列是否为空
bool QueueEmpty(Queue* pq)
{
	assert(pq);
	return pq->phead == NULL && pq->ptail == NULL;
}
// 队头出队列 
void QueuePop(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));
	//1.一个结点
	//2.多个结点
	if (pq->phead->next == NULL)
	{
		free(pq->phead);
		pq->phead = pq->ptail = NULL;
	}
	else
	{
		//相当于头删
		QueueNode* next = pq->phead->next;
		free(pq->phead);
		pq->phead = next;
	}
	pq->size--;
}
// 获取队列头部元素 
QDataType QueueFront(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));
	return pq->phead->data;
}

// 获取队列队尾元素 
QDataType QueueBack(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));
	return pq->ptail->data;
}

// 获取队列中有效元素个数 
int QueueSize(Queue* pq)
{
	assert(pq);
	return pq->size;
}

Layer sequence traversal source code:

//层序遍历
void LevelOrder(BTNode* root)
{
	Queue q;
	QueueInit(&q);
	if (root != NULL)
	{
		QueuePush(&q, root);
	}
	while (!QueueEmpty(&q))
	{
		BTNode* front = QueueFront(&q);
		QueuePop(&q);
		printf("%d ", front->data);
		if (front->left != NULL)
		{
			QueuePush(&q, front->left);
		}
		if (front->right != NULL)
		{
			QueuePush(&q, front->right);
		}
	}
	printf("\n");
	QueueDestroy(&q);
}

 


Binary tree destruction

//二叉树销毁
void BTreeDestroy(BTNode* root)
{
	if (root == NULL)
	{
		return;
	}
	BTreeDestroy(root->left);
	BTreeDestroy(root->right);
	free(root);
}

 

Build a binary tree through the array " ABD # # E # H # # CF # # G # # " traversed in preorder

root left subtree right subtree

 

#include <stdio.h>
#include<stdlib.h>
typedef int BTDataType;
typedef struct BinaryTreeNode
{
	BTDataType data;
	struct BinaryTreeNode* left;
	struct BinaryTreeNode* right;
}BTNode;

BTNode* BuyNode(BTDataType x)
{
	BTNode* node = (BTNode*)malloc(sizeof(BTNode));
	if (node == NULL)
	{
		perror("malloc fail");
		return NULL;
	}
	node->data = x;
	node->left = NULL;
	node->right = NULL;
	return node;
}
BTNode* CreatTree(char* a,int* pi)
{
    if(a[*pi]=='#')
    {
        (*pi)++;
        return NULL;
    }
    BTNode* root=BuyNode(a[*pi]);
    (*pi)++;
    root->left=CreatTree(a,pi);
    root->right=CreatTree(a,pi);
    return root;
}
//中序
void InOrder(BTNode* root)
{
	if (root == NULL)
	{
		return;
	}
	InOrder(root->left);
	printf("%c ", root->data);
	InOrder(root->right);
}
int main()
{
    char a[100];
    scanf("%s",a);
    int i=0;
    BTNode*root=CreatTree(a,&i);
    InOrder(root);
    printf("\n");
    return 0;

}

 

 

 

Determine whether a binary tree is a complete binary tree

The characteristics of a complete binary tree are: go through the sequence traversal, it is continuous! ! !

 

1 comes out with 2 and 4, 2 comes out with 3 and NULL, 4 comes out with 5 and 6, 3 comes out with NULL and NULL, but there is a non-empty behind NULL after 3, which proves that this tree is a Incomplete binary tree.

 

1 comes out with 2 and 4, 2 comes out with 3 and 7, 4 comes out with 5 and 6, 3 comes out with 8 and NULL, 7 comes out with NULL and NULL, 5 comes out with NULL and NULL, 6 comes out with NULL and NULL, 8 Come out with NULL and NULL, that is to say, all the queues are empty, this must be a complete binary tree.

//判断二叉树是否是完全二叉树
bool BTreeComplete(BTNode* root)
{
	Queue q;
	QueueInit(&q);
	if (root != NULL)
	{
		QueuePush(&q, root);
	}
	while (!QueueEmpty(&q))
	{
		BTNode* front = QueueFront(&q);
		QueuePop(&q);
		//遇到空就跳出循环
		if (front == NULL)
		{
			break;
		}
		QueuePush(&q, front->left);
		QueuePush(&q, front->right);
	}
	//检查后面的结点有没有非空
	//有非空,就不是完全二叉树
	while (!QueueEmpty(&q))
	{
		BTNode* front = QueueFront(&q);
		QueuePop(&q);
		if (front != NULL)
		{
			QueueDestroy(&q);
			return false;
		}
	}
	QueueDestroy(&q);
	return true;
}

 


1. The sequence of a complete binary tree output by level (from left to right at the same level) is ABCDEFGH. The preorder sequence of the complete binary tree is ( A )

A ABDHECFG

B ABCDEFGH

C HDBEAFCG

D HDEBFGCA

2. The pre-order traversal and in-order traversal of the binary tree are as follows: pre-order traversal: EFHIGJK; in-order traversal: HFIEJKG. Then the root node of the binary tree is ( A )

AE

B F

C G

D H

This question has nothing to do with in-order traversal (in-order traversal is confusing). Just look at pre-order traversal and you can see that pre-order traversal is the root + left subtree + right subtree, so E is the root node.

But if you want to restore this binary tree, in-order traversal is very important! ! !

 

3. Suppose the in-order traversal sequence of a binary tree: badce, and the post-order traversal sequence: bdeca, then the pre-order traversal sequence of the binary tree is ( D ).

A adbce

B decab

C debac

D abcde

The last one in the post-order traversal sequence is a, so a is the root node! ! !

4. The post-order traversal sequence of a binary tree is the same as the in-order traversal sequence, both are ABCDEF, then the sequence output by level (from left to right at the same level) is (A)

A FEDCBA

B CBAFED

C DEFCBA

D ABCDEF

Properties of Binary Trees

 

 


The source code of the entire binary tree:

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include"Queue.h"
typedef int BTDataType;
typedef struct BinaryTreeNode
{
    BTDataType data;
    struct BinaryTreeNode* left;
    struct BinaryTreeNode* right;
}BTNode;

BTNode* BuyNode(BTDataType x)
{
    BTNode* node = (BTNode*)malloc(sizeof(BTNode));
    if (node == NULL)
    {
        perror("malloc fail");
        return NULL;
    }
    node->data = x;
    node->left = NULL;
    node->right = NULL;
    return node;
}

BTNode* CreatBinaryTree()
{
    BTNode* node1 = BuyNode(1);
    BTNode* node2 = BuyNode(2);
    BTNode* node3 = BuyNode(3);
    BTNode* node4 = BuyNode(4);
    BTNode* node5 = BuyNode(5);
    BTNode* node6 = BuyNode(6);

    node1->left = node2;
    node1->right = node4;
    node2->left = node3;
    node4->left = node5;
    node4->right = node6;
    return node1;
}

//前序
void PrevOrder(BTNode* root)
{
    if (root == NULL)
    {
        printf("NULL ");
        return;
    }
    printf("%d ", root->data);
    PrevOrder(root->left);
    PrevOrder(root->right);
}

//中序
void InOrder(BTNode* root)
{
    if (root == NULL)
    {
        printf("NULL ");
        return;
    }
    InOrder(root->left);
    printf("%d ", root->data);
    InOrder(root->right);
}

//后序
void PostOrder(BTNode* root)
{
    if (root == NULL)
    {
        printf("NULL ");
        return;
    }
    PostOrder(root->left);
    PostOrder(root->right);
    printf("%d ", root->data);
}

 

Number of binary tree nodes
//int size = 0;//Global variable
//int BTreeSize(BTNode* root)
//{ // if (root == NULL) // { // return; // } // else // { // ++size; // } // BTreeSize(root->left); // BTreeSize(root->right); //} Number of binary tree nodes //int BTreeSize(BTNode* root) / /{ // if (root == NULL) // { // return 0; // } // else // { // return BTreeSize(root->left) + BTreeSize(root->right) + 1; / / } //}























//Number of binary tree nodes
int BTreeSize(BTNode* root)
{     return root == NULL ? 0 : BTreeSize(root->left) + BTreeSize(root->right) + 1; }


//Verify the default value
int BTreeleafSize(BTNode* root)
{     if (root == NULL)     {         return 0;     }     if ( root - > left == NULL & & root - > right == NULL )     {         return 1 ;     }     return BTreeleafSize(root->left) + BTreeleafSize(root->right); } }









// uncheck the boundary
int BTreeHeight(BTNode* root)
{     if (root == NULL)     {         return 0;     }     else     {         int leftHeight = BTreeHeight(root->left);         int rightHeight = BTreeHeight(root->right);         return leftHeight > rightHeight ? leftHeight + 1 : rightHeight + 1;     } } }











// The number of nodes in the kth layer of the binary tree
int BTreeLevelKSize(BTNode* root, int k)
{     assert(k > 0);     if (root == NULL)//No matter how much k is     {         return 0;     }     //root must not Empty     if (k == 1)     {         return 1;     }     //root is not empty and k is not 1     return BTreeLevelKSize(root->left, k - 1) + BTreeLevelKSize(root->right, k - 1); }













//
BTNode* BTreeFind(BTNode* root, BTDataType x)
{     if (root == NULL)     {         return NULL;     }     if (root->data == x)     {         return root;     }     BTNode* ret1 = BTreeFind(root->left, x);     if (ret1)     {         return ret1;     }     BTNode* ret2 = BTreeFind(root->right, x);     if (ret2)     {         return ret2;     }     return NULL; }




















//层序遍历
void LevelOrder(BTNode* root)
{
    Queue q;
    QueueInit(&q);
    if (root != NULL)
    {
        QueuePush(&q, root);
    }
    while (!QueueEmpty(&q))
    {
        BTNode* front = QueueFront(&q);
        QueuePop(&q);
        printf("%d ", front->data);
        if (front->left != NULL)
        {
            QueuePush(&q, front->left);
        }
        if (front->right != NULL)
        {
            QueuePush(&q, front->right);
        }
    }
    printf("\n");
    QueueDestroy(&q);
}


//二叉树销毁
void BTreeDestroy(BTNode* root)
{
    if (root == NULL)
    {
        return;
    }
    BTreeDestroy(root->left);
    BTreeDestroy(root->right);
    free(root);
}


//Judge whether the binary tree is a complete binary tree
bool BTreeComplete(BTNode* root)
{     Queue q;     QueueInit(&q);     if (root != NULL)     {         QueuePush(&q, root);     }     while (!QueueEmpty(&q))     {         BTNode * front = QueueFront(&q);         QueuePop(&q);         //Jump out of the loop         if (front == NULL)         {             break;         }         QueuePush(&q, front->left);         QueuePush(&q, front->right );     }     //Check whether the following nodes are non-empty     //If there is non-empty, it is not a complete binary tree     while (!QueueEmpty(&q))     {






















        BTNode* front = QueueFront(&q);
        QueuePop(&q);
        if (front != NULL)
        {
            QueueDestroy(&q);
            return false;
        }
    }
    QueueDestroy(&q);
    return true;
}

int main()
{
    BTNode* root = CreatBinaryTree();
    PrevOrder(root);
    printf("\n");

    InOrder(root);
    printf("\n");

    PostOrder(root);
    printf("\n");

    /*BTreeSize(root);
    printf("BTreeSize:%d\n", size);

    size = 0;
    BTreeSize(root);
    printf("BTreeSize:%d\n", size);

    size = 0;
    BTreeSize(root);
    printf("BTreeSize:%d\n", size);*/

    printf("BTreeSize:%d\n",BTreeSize(root));

    printf("BTreeleafSize:%d\n", BTreeleafSize(root));

    printf("BTreeHeight:%d\n", BTreeHeight(root));

    printf("BTreeLevelKSize:%d\n", BTreeLevelKSize(root, 3));

    printf("BTreeFind:%p\n", BTreeFind(root, 3));

    LevelOrder(root);

    BTreeDestroy(root);
    root = NULL;

    return 0;
}

 

Alright, this is the end of Xiao Yalan's sharing today, let's continue to work hard and learn! ! !

 

 

Guess you like

Origin blog.csdn.net/weixin_74957752/article/details/131752629