Tree and Binary Tree Basics

introduction:

A tree is a non-linear structure and is also composed of nodes one by one .

Some basic concepts of trees:

Degree of node: The number of subtrees contained in a node is called the degree of the node; as shown in the figure above: the degree of A is 6

Leaf Node or Terminal Node: A node with degree 0 is called a leaf node.

Non-terminal node or branch node: a node whose degree is not 0;

Parent node or parent node: If a node contains child nodes, this node is called the parent node of its child nodes.

Child node or child node: For example, B is a child node of A.

Brother nodes: Nodes with the same parent node are called sibling nodes

Degree of tree: In a tree, the degree of the largest node is called the degree of the tree

Node hierarchy: defined from the root, the root is the first level, the child nodes of the root are the second level, and so on.

Tree height or depth: the maximum level of nodes in the tree, as shown above: the height of the tree is 4. ( Note that counting starts from 1, which also means that an empty tree is 0 )

tree representation

Left-child right-sibling notation:

Binary tree concept and structure

concept:

  • Each node has at most two subtrees , that is, there is no node with degree greater than 2 in the binary tree.
  • The subtrees of the binary tree are divided into left and right, and the order of the subtrees cannot be reversed. ,

Definition of binary tree

Because there are at most two children, you can directly define the left child and the right child.

Pre-order, middle-order and post-order of binary tree

First of all, it is necessary to clarify that any binary tree is divided into 3 parts:

  1. root node
  2. left subtree
  3. right subtree

Note that the left subtree and the right subtree are a whole , and then subdivide the root node, left subtree, and right subtree from this whole.

Preorder (root first): root left subtree right subtree

Inorder: left subtree root right subtree

Postorder: left subtree right subtree root

The order of the front, middle and back is determined according to the position of the root

The following is the original code of the front, middle and post sequence (use recursion to solve)

void PrevOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("NULL ");
		return;
	}
	printf("%c ", root->val);
	PrevOrder(root->left);
	PrevOrder(root->right);
}

void InOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("NULL ");
		return;
	}
	InOrder(root->left);
	printf("%c ", root->val);
	InOrder(root->right);
}

void PostOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("NULL ");
		return;
	}
	PostOrder(root->left);
	PostOrder(root->right);
	printf("%c ", root->val);
}

special binary tree

  1. Full binary tree: a binary tree, if the node tree of each layer reaches the maximum value, it is called a full binary tree
  2. Complete binary tree: On the basis of a full binary tree, the first h-1 layers are full, but the last layer is not full , but the last layer is continuous from left to right .

Properties of Binary Trees

  1. If the number of layers of the root node is specified as 1, then there are at most 2^(i-1) nodes on the i-th layer of a non-empty binary tree.
  2. If the number of layers of the root node is specified as 1, then the maximum number of nodes of the binary tree with depth h (that is, the number of full binary trees) is 2^h-1
  3. For any binary tree, if the number of leaf nodes with degree 0 is n0, and the number of branch nodes with degree 2 is n2, then n0 = n2+1.
  4. If the number of layers of the root node is specified as 1, the depth h = LogN of a full binary tree with n nodes .

Solve problems according to the properties of binary trees

Example 1:

The number of leaf nodes obtained from the property 3 of the binary tree is the number of branch nodes with degree 2+1 , so directly 199+1 = 200.

Example 2:

Multiple choice quick method:

Assume n = 2 directly , then carry out calculations, and compare with each option to get the correct answer.

Conventional solution:

Assuming an unknown number, the number of nodes with degree 0 is X0, the number of nodes with degree 1 is X1, and the number of nodes with degree 2 is X2.

Will get X0+X1+X2 = 2n.

And because of the relationship between X0 and X2, X2+1 = X0.

And because it is a complete binary tree, the number of nodes with a degree of 1 is either 1 or 0 , so in two cases, it is found that when X1 = 1, the calculation result is a decimal, which does not meet the meaning of the question, so X1 = 0 to get Answer.

Example 3:

answer:

Assume that the height of the tree is h, assuming that the last layer is missing X

This question is also to bring the answers of the multiple choice questions to the question for comparison, and then get the correct answer.

How to find the number of nodes in a binary tree?

Solution one:

The idea of ​​using loop traversal

Traverse each node of this tree, if it is not empty, size++, otherwise no ++.

Note that when using this method, it may be necessary to calculate the nodes of multiple trees, so each time a parameter is passed, a new size address needs to be passed, and the value of size is directly printed out in the main function

Original code:
void TreeSize(BTNode* root,int* psize)//直接传地址
{
	if (root == NULL)
		return;
	else
	{
		(*psize)++;
		TreeSize(root->left, psize);
		TreeSize(root->right, psize);
	}
}

Solution two:

Adopt the idea of ​​divide and conquer .

What is the idea of ​​​​divide and conquer, is to decompose a more complex problem layer by layer until it is decomposed to a simple level. Break down big problems into smaller ones.

For example, the principal wants to count the number of people in the whole school. The principal assigns this task to the dean, who then assigns it to the head teacher of each class, and each head teacher to the dormitory head of each dormitory.

The idea of ​​this question is also the same. Count the number of nodes in the whole tree, divide the tree into left subtree and right subtree, and then divide the left subtree into small left subtree and small right subtree, recursively , until the last layer is incremented by 1.

Original code:

int TreeSize(BTNode* root)
{
	return root == NULL ? 0 : TreeSize(root->left) + TreeSize(root->right) + 1;
	/*if (root == NULL)
		return 0;
	else
	{
		return TreeSize(root->left) + TreeSize(root->right) + 1;
	}*/
}

How to find the number of leaf nodes in a binary tree?

According to the idea of ​​the above branch, let's draw inferences~

int TreeLeafSize(BTNode* root)
{
	if (root == NULL)
		return 0;
	if (root->left == NULL && root->right == NULL)
		return 1;
	else
		return TreeLeafSize(root->left) + TreeLeafSize(root->right);
}

TIP:

You only need to give the inorder + any preorder or postorder to restore a complete binary tree .

reason:

Both the preorder and the inorder know which root node is, but they don't know the left subtree and the right subtree.

If there is an inorder and the root node is known, then in the inorder arrangement, the left subtree is to the left of the root node, and the right subtree is to the right of the root node, and the tree can be easily restored.

Some classic examples about binary trees

Example 1: Preorder traversal of a binary tree

144. Preorder Traversal of Binary Tree - LeetCode

Title description:

Precautions:

Use the idea of ​​recursion to perform preorder traversal. Note that when recursing, counters generally need to pass addresses to prevent local variables from being automatically destroyed when they exit the life cycle.

It is not acceptable to assume that the counter uses global variables .

Because the function interface will be called multiple times, global variables will always accumulate !

Original code:

//提前计算好树的结点的个数,方便创建动态数组的个数
int TreeSize(struct TreeNode* root)
{
    return root == NULL ? 0 : TreeSize(root->left) + TreeSize(root->right) + 1;
}

void _PrevOrder(struct TreeNode* root,int* arr,int* pcnt)
{
    //前序递归遍历,将遍历的结点存储到动态数组中
    if(root == NULL)
        return;
    arr[*pcnt] = root->val;
    (*pcnt)++;
    _PrevOrder(root->left,arr,pcnt);
    _PrevOrder(root->right,arr,pcnt);
}


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

    int size = TreeSize(root);
    int* arr = (int*)malloc(sizeof(int) * size);
    int cnt = 0;
    //注意传地址,递归调用一般需要传址操作
    _PrevOrder(root,arr,&cnt);
    *returnSize = cnt;
    return arr;
}

Example 2: The maximum depth of a binary tree

104. The Maximum Depth of a Binary Tree - LeetCode

Title description:

Problem-solving ideas:

Also adopt the idea of ​​​​divide and conquer, to find the maximum depth of the binary tree, is to find the maximum depth of the left subtree and the right subtree, and then continue to divide and conquer, to find the maximum depth of the small left subtree and small right subtree in the left subtree, Until it can't be decomposed, it can be +1

Original code:

int maxDepth(struct TreeNode* root){
    if(root == NULL)
        return 0;
    int leftmax = maxDepth(root->left) + 1;
    int rightmax = maxDepth(root->right) + 1;
    return leftmax > rightmax ? leftmax : rightmax;
}

Example 3: Judging a balanced binary tree

110. Balanced Binary Tree - LeetCode

Title description:

Problem-solving ideas:

This question requires each node of the binary tree to satisfy that the absolute value of the height difference between the left and right subtrees does not exceed 1, so first judge whether the left and right subtrees of the head node are satisfied, and if the head node is not satisfied, then return directly false .

If the head node is satisfied, continue to recurse down whether the nodes of the left and right subtrees are satisfied.

Original code:

int MaxDepth(struct TreeNode* root)
{
    if(root == NULL)
        return 0;
    int leftDepth = MaxDepth(root->left);
    int rightDepth = MaxDepth(root->right);
    return leftDepth > rightDepth ? leftDepth+1 : rightDepth+1;
}

bool isBalanced(struct TreeNode* root){
    if(root == NULL)
        return true;
    //先判断头结点,接着再判断子节点
    int leftDepth = MaxDepth(root->left);
    int rightDepth = MaxDepth(root->right);
    return  abs(leftDepth-rightDepth) < 2 && isBalanced(root->left) && isBalanced(root->right);
}

Guess you like

Origin blog.csdn.net/hanwangyyds/article/details/132588981