Solving Problems Related to Binary Tree and Its OJ Consolidation


Preface: Consolidate the basic knowledge of binary trees. We have learned the related properties of binary trees. Now let's solve the problems of the height and number of nodes of binary trees.

1. Solve the basic concept of binary tree

  Assuming that there is a binary tree, how should we know its height, number of layers and other relevant information, below we use the recursive nature of the binary tree to solve it in turn.

1 Find the number of summary points in the binary tree

(1) Pass count variable address without return value

  To find the number of nodes, we cannot create a temporary counting variable in the function. The change of the formal parameter does not affect the actual parameter. When the recursion comes out, the scope will be destroyed, so we need to pass the address of the temporary variable.

void TreeSize(BTNode* root, int* size)
{
    
    
	if (root == NULL)
		return;
	*size += 1;
	TreeSize(root->left, size);
	TreeSize(root->right, size);
}

(2) Divide and conquer with return value

  The recursion end condition is that the node is empty, then return 0, otherwise return the sum of the number of nodes in the left and right subtrees + 1, where the count is the root node.

int TreeSize1(BTNode* root)
{
    
    
	if (root == NULL)
		return 0;
	return TreeSize1(root->left) + TreeSize1(root->right) + 1;
	//加一加的是根结点
}

2 Find the height of the binary tree

  A binary tree can be composed of its left subtree and right subtree, and the height of the binary tree can be calculated by the height of the left and right subtrees. When the root node is empty, return 0, and when the root node is not empty, return the greater height of the left and right subtrees + 1, plus one refers to the layer where the root is added.

int TreeHeight(BTNode* root)
{
    
    
	if (root == NULL)
		return 0;
	int Left = TreeHeight(root->left);
	int Right = TreeHeight(root->right);
	int max = Left > Right ? Left : Right;
	return max + 1;
}//求高度

3 Find the number of nodes in the kth layer

  The k-th layer needs to recurse down k-1 times relative to the first layer, and needs to recurse k-2 times relative to the second layer, so it needs to recurse k-1 times to get to the k-th layer, and k==1 at this time. If k>number of layers, return to 0 if it goes empty ahead of time. When k is 1, return the node 1, otherwise return the sum of the left and right subtrees.

int TreeKLevel(BTNode* root, int k)
{
    
    
	//走不到第k层就空了
	if (root == NULL)
		return 0;
		//当k=1时每次访问结点都返回1
	if (k == 1) //相对位置关系,走到第k层说明要走k-1次,目标层是k==1
		return 1;
	else
		return TreeKLevel(root->left, k - 1) + TreeKLevel(root->right, k - 1);
}

4 Level order traversal of binary tree - queue

  To traverse the layers of the binary tree, we need to use the first-in-first-out nature of the queue. If the root node is not empty, then the root node will enter the queue. Then put its left and right children into the team. At this time, we need to dequeue the parents whose left and right children have already joined the team, so that one of the left and right children becomes the root node again, and its children can be allowed to join the team. Note that the queue stores the pointer of the node, and the node can be accessed with the address of the node, and there is no need to store the entire node.

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

5 Determine whether it is a complete binary tree

  With the experience of the above sequence traversal, as long as the root node is not empty, we will join the left and right children into the team.

We can find that if it is a complete binary tree and NULL is encountered when leaving the queue, then if we jump out of the loop, the remaining node addresses in the queue should all be NULL.

If it is not a complete binary tree, then when the queue reaches NULL, jump out of the loop, and there must be addresses that are not NULL in the queue.

bool TreeComplete(BTNode* root)
{
    
    
	Queue q;
	QueueInit(&q);
	//先让队列进一个数据才能循环起来
	QueuePush(&q, root);
	while (!QueueEmpty(&q))
	{
    
    
		BTNode* head = QueueFront(&q);
		QueuePop(&q);
			//删除根结点地址在入它的孩子
		if (head != NULL)
		{
    
    
			QueuePush(&q, head->left);
			QueuePush(&q, head->right);
		}
		else	//队出空则跳出循环
		{
    
    
			break;
		}
	}

	while (!QueueEmpty(&q))
	{
    
    
		if (QueueFront(&q))
		{
    
    
			//进到这说明地址不是NULL
			QueueDestroy(&q);
			return false;
		}
		QueuePop(&q);
	}
	QueueDestroy(&q);
	return true;
}

2. Ritou-related OJ consolidates the foundation

1 Single-valued binary tree

(1) Topic entry

965. Single Valued Binary Tree

(2) Idea + code

  If a tree is a current value binary tree, then all node values ​​are equal, because the nature of the tree is recursive, we only need to compare whether a group of roots and the values ​​​​of the left and right nodes are equal, and then proceed recursively.


2 identical trees

(1) Topic entry

100. The same tree

(2) Idea plus code

  Like the single-value binary tree, we first compare the left and right nodes of the root and then recursively compare down.


3 Flip the binary tree

(1) Topic entry

226. Flip Binary Tree



(2) Idea plus code

  To flip a tree, we can flip it from top to bottom, so that the left and right children of the root are flipped, and then flipped recursively. Personally, I think it is clearer to flip the hierarchy from top to bottom.


4. Symmetric binary tree

(1) Topic entry

101. Symmetric Binary Tree

(2) Idea plus code

  With the same tree topic experience above, that topic is two trees walking in one direction at the same time for comparison. As for the symmetric binary tree, we regard a tree as two trees, call ourselves, and if one tree goes to the left, the other tree goes in the opposite direction to judge whether it is symmetrical.
bold style

5 subtrees of another tree

(1) Topic entry

572. A Subtree of Another Tree

(2) Idea plus code

  After writing the previous single-valued binary tree, the idea of ​​this question is similar. Start the comparison from the root first, not compare the left and right subtrees. Recursively, here you only need to call the auxiliary function of judging the same tree, that is, recursion nests a layer of recursion.


3. Summary

  This knowledge is still at the elementary level of binary tree knowledge. After the foundation is consolidated, it will be much easier to learn complex binary tree knowledge. I look forward to seeing you in the next blog.

Guess you like

Origin blog.csdn.net/Front123456/article/details/130030751