Article directory
1. Binary tree traversal
The binary tree nodes in all the codes below:
typedef char BTDataType;
//二叉树结点结构体
typedef struct BinaryTreeNode
{
BTDataType data;
struct BinaryTreeNode* left;
struct BinaryTreeNode* right;
}BTNode;
1. Preorder traversal
Preorder, middle, and postorder traversals can all be solved using the idea of divide-and-conquer recursion, and the root node and its child nodes are processed separately.
// 二叉树前序遍历
void BinaryTreePrevOrder(BTNode* root)
{
if (root == NULL)
{
printf("NULL ");
return;
}
printf("%c ", root->data);
BinaryTreePrevOrder(root->left);
BinaryTreePrevOrder(root->right);
}
Here we only use the recursive expansion graph to analyze pre-order traversal. The same idea is used in in-order and post-order:
2. In-order traversal
// 二叉树中序遍历
void BinaryTreeInOrder(BTNode* root)
{
if (root == NULL)
{
printf("NULL ");
return;
}
BinaryTreeInOrder(root->left);
printf("%c ", root->data);
BinaryTreeInOrder(root->right);
}
3. Post-order traversal
// 二叉树后序遍历
void BinaryTreePostOrder(BTNode* root)
{
if (root == NULL)
{
printf("NULL ");
return;
}
BinaryTreePostOrder(root->left);
BinaryTreePostOrder(root->right);
printf("%c ", root->data);
}
4. Layer sequential traversal
Level order traversal needs to be performed using a queue. If the binary tree and node are not empty, letenqueue a pointer to it, then record the head node of the queue, print its value first, then judge that its left and right children are non-empty and then join the queue, then delete the head of the queue and replace it with the next one to continue recording and printing... until the queue is empty and the traversal is completed.
For example, consider this binary tree as shown:
The result of layer sequence traversal is: 12345.
First, put the root node 1 into the queue and print 1
Then add the left and right children 2 and 3 of 1 into the team
Delete the head of the queue 1, replace front with 2, and print 2
Then add the left child 4 of 2 to the team
Delete the head 2, replace front with 3, and print 3
Then add the right child 5 of 3 to the team
… …
Then print 4 and 5 like this to complete the level-order traversal of the binary tree.
The program code uses the queue created by itself. The code is as follows:
//层序遍历
void LevelOrder(BTNode* root)
{
//创建队列
Que q;
QueueInit(&q);
//如果根节点不为空,则放进队列
if (root)
QueuePush(&q, root);
while (!QueueEmpty(&q))
{
//将队头打印
BTNode* front = QueueFront(&q);
printf("%c ", front->data);
//判断front左右节点不为空则入队
if (front->left)
QueuePush(&q, front->left);
if (front->right)
QueuePush(&q, front->right);
QueuePop(&q);
}
printf("\n");
QueueDestroy(&q);
}
2. Number and height of binary tree nodes
1. Number of binary tree nodes
It is implemented recursively using the divide-and-conquer method. When the root node is empty, the return value is 0. If it is not empty, it returns the number of nodes on the left and right subtrees plus 1.
int BinaryTreeSize(BTNode* root)
{
return root == NULL ? 0 : BinaryTreeSize(root->left) + BinaryTreeSize(root->right) + 1;
}
2. Number of leaf nodes of binary tree
It is implemented recursively using the divide-and-conquer method. When the root node is empty, 0 is returned. When the root node has no child nodes, it means it is a leaf node, and 1 is returned. In other cases, just add the leaf nodes on the left and right subtrees.
int BinaryTreeLeafSize(BTNode* root)
{
if (root == NULL)
{
return 0;
}
if (root->left == NULL && root->right == NULL)
{
return 1;
}
return BinaryTreeLeafSize(root->left) + BinaryTreeLeafSize(root->right);
}
3. Number of nodes at the kth level of the binary tree
You need to ensure that k is greater than 0. When the root node is empty, 0 is returned. When k is equal to 1, there is only one node in one layer, and 1 is returned. When k>1, the number of nodes in the kth layer is equivalent to the kth child of its left and right children. -The number of nodes in layer 1 is added up.
int BinaryTreeLevelKSize(BTNode* root, int k)
{
assert(k > 0);
if (root == NULL)
{
return 0;
}
if (k == 1)
{
return 1;
}
return BinaryTreeLevelKSize(root->left, k - 1)
+ BinaryTreeLevelKSize(root->right, k - 1);
}
4. Find the node with value x in a binary tree
If the following node is empty, NULL is returned if it cannot be found. When the value of the root node is the value you are looking for, the node is returned. If they are not equal, its left and right child nodes are judged respectively until they are found.
BTNode* BinaryTreeFind(BTNode* root, BTDataType x)
{
if (root == NULL)
{
return NULL;
}
if (root->data == x)
{
return root;
}
BTNode* ret = BinaryTreeFind(root->left,x);
if (ret)
{
return ret;
}
return BinaryTreeFind(root->right, x);
}
3. Binary tree creation and destruction
1. Create a binary tree by traversing the array in preorder
Read a preorder traversal string input by the user, and build a binary tree (stored as a pointer) based on this string. For example, the following pre-order traversal string: ABC##DE#G##F### where "#" represents a space, and the space character represents an empty tree. After establishing the binary tree, perform an in-order traversal on the binary tree and output the traversal results.
#include <stdio.h>
#include<stdlib.h>
typedef char BTDataType;
typedef struct BinaryTreeNode {
BTDataType data;
struct BinaryTreeNode* left;
struct BinaryTreeNode* right;
} BTNode;
BTNode* BinaryTreeCreate(BTDataType* a, int* pi) {
if (a[*pi] == '#') {
++*pi;
return NULL;
}
BTNode* root = (BTNode*)malloc(sizeof(BTDataType));
root->data = a[*pi];
++*pi;
root->left = BinaryTreeCreate(a, pi);
root->right = BinaryTreeCreate(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 pi=0;
BTNode* root=BinaryTreeCreate(a, &pi);
InOrder(root);
return 0;
}
2. Destruction of binary trees
void BinaryTreeDestory(BTNode* root)
{
if (root == NULL)
{
return;
}
BinaryTreeDestory(root->left);
BinaryTreeDestory(root->right);
free(root);
}
3. Determine whether it is a complete binary tree
Modify the binary tree level-order traversal so that empty nodes also enter the queue. When traversing an empty node, it will exit. If there are non-empty nodes before the end of the traversal, it is not a complete binary tree.
int BinaryTreeComplete(BTNode* root)
{
//创建队列
Que q;
QueueInit(&q);
//如果根节点不为空,则放进队列
if (root)
QueuePush(&q, root);
while (!QueueEmpty(&q))
{
BTNode* front = QueueFront(&q);
if (front == NULL)
{
break;
}
QueuePush(&q, front->left);
QueuePush(&q, front->right);
QueuePop(&q);
}
//此时已经遇到空节点,如果再遇到非空节点则不是完全二叉树
while (!QueueEmpty(&q))
{
BTNode* front = QueueFront(&q);
if (front)
{
QueueDestroy(&q);
return false;
}
QueuePop(&q);
}
QueueDestroy(&q);
return true;
}
4. Test code
Manually build a binary tree as shown below and test the code:
the test result should be:
Preorder: 123874569
Middle sequence: 832715469
Postorder: 837259641
Whether it is a complete binary tree: 0
Number of nodes: 9
Number of leaf nodes: 4
BTNode* BuyNode(BTDataType x)
{
BTNode* node = (BTNode*)malloc(sizeof(BTNode));
if (node == NULL)
{
perror("malloc fail");
exit(-1);
}
node->data = x;
node->left = NULL;
node->right = NULL;
return node;
}
int main()
{
// 手动构建
BTNode* node1 = BuyNode('1');
BTNode* node2 = BuyNode('2');
BTNode* node3 = BuyNode('3');
BTNode* node4 = BuyNode('4');
BTNode* node5 = BuyNode('5');
BTNode* node6 = BuyNode('6');
BTNode* node7 = BuyNode('7');
BTNode* node8 = BuyNode('8');
BTNode* node9 = BuyNode('9');
node1->left = node2;
node1->right = node4;
node2->left = node3;
node4->left = node5;
node4->right = node6;
node2->right = node7;
node3->left = node8;
node6->right = node9;
printf("前序遍历:");
BinaryTreePrevOrder(node1);
printf("\n");
printf("中序遍历:");
BinaryTreeInOrder(node1);
printf("\n");
printf("后序遍历:");
BinaryTreePostOrder(node1);
printf("\n");
printf("层序遍历:");
LevelOrder(node1);
printf("\n");
printf("BinaryTreeComplete:%d\n", BinaryTreeComplete(node1));
printf("BinaryTreeSize:%d\n", BinaryTreeSize(node1));
printf("BinaryTreeLeafSize:%d\n", BinaryTreeLeafSize(node1));
BinaryTreeDestory(node1);
node1 = NULL;
return 0;
}
operation result:
The running results are consistent with the predicted results.