Data structure: recursive implementation of binary tree (C implementation)

insert image description here

Personal homepage: Personal homepage
Personal column: "Data Structure" "C Language"


foreword

This blog mainly explains the related operations of the binary tree as follows:

//通过前序遍历的数组"ABD##E#H##CF##G##"构建二叉树
BTNode* BinaryTreeCreate(BTDataType* a, int n, int* pi);

//二叉树的销毁
void BinaryTreeDestroy(BTNode* root);

//二叉树节点个数
int BinaryTreeSize(BTNode* root);

//二叉树叶子节点个数
int BinaryTreeLeafSize(BTNode* root);

//二叉树第K层节点个数
int BinaryTreeLevelKSize(BTNode* root, int k);

//二叉树查找值为X的节点
BTNode* BinaryTreeFind(BTNode* root, BTDataType x);

//二叉树前序遍历
void BinaryTreePrevOrder(BTNode* root);

//二叉树中序遍历
void BinaryTreeInOrder(BTNode* root);

//二叉树后序遍历
void BinaryTreePostOrder(BTNode* root);

//层序遍历
void BinaryTreeLevelOrder(BTNode* root);

//判断二叉树是否是完全二叉树
bool BinaryTreeComplete(BTNode* root);

//创建二叉树的节点
BTNode* BuyBinaryTreeNode(BTDataType x);

1. The concept of tree

A tree is a nonlinear structure, which is a collection of hierarchical relationships composed of n finite nodes.

insert image description here

  • Node A in the figure has no predecessor node and is called the root node
  • Except the root node, other nodes are divided into two non-disjoint sets T1 (B, D, E, F...), T2 (C, G, H, L...). Each set T is a subtree similar in structure to a tree. The root node of each subtree has one and only one root node, and can have 0 or more successor nodes
  • Therefore, the tree is defined recursively.
  • The subtrees of the tree cannot have intersection, otherwise it is a graph.

  • 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 node A is 2
  • Leaf node or terminal node : a node with a degree of 0 is called a leaf node; as shown in the figure above: K, J, F, L, O, P are leaf nodes
  • Non-terminal node or branch node : a node whose degree is not 0; as shown in the figure above: nodes such as A, B, C, D, E, etc. are branch nodes
  • Parent node or parent node : If a node contains child nodes, this node is called the parent node of its child nodes. As shown above, node A is the parent node of B and C
  • Child node or child node : If a node contains a subtree, the root node of the subtree is the child node of the node. As shown in the above figure B, C is a child node of A
  • Brother nodes : Nodes with the same parent node are sibling nodes. As shown above, B and C are sibling nodes
  • Degree of the tree : In a tree, the degree of the largest node is the degree of the number. The degree of the number in the above figure is 3
  • Node hierarchy : starting from the definition of the root, the root is the first layer, the child nodes of the root are the second layer, and so on. As shown in the figure above, the level of the G node is 3
  • Tree height or depth : The maximum level of nodes in the tree. As shown above, the depth of the tree is 5
  • Cousin nodes : Nodes whose parent nodes are on the same layer are cousin nodes. As shown above, D and G are cousin nodes of each other
  • Ancestors of a node : all nodes on the branch from the root to the node. As shown above, A is the ancestor of all nodes
  • Descendant node : Any node in the subtree rooted at a node is called a descendant of the node. As shown above, the node is a descendant of A
  • Forest : A collection of m disjoint trees is called a forest

Second, the binary tree

The concept of binary tree

It consists of a root node plus two subtrees.

insert image description here

  • The maximum degree of a binary tree is 2
  • A binary tree is an ordered tree. The subtrees of the binary tree are divided into left and right, and the order cannot be reversed.

Properties of Binary Trees

If the number of layers of the root node is specified to be 1, then the Kth layer of a non-empty binary tree has at most 2^(k - 1) nodes

If the number of layers of the root node is specified to be 1, then the maximum number of nodes in a binary tree with a depth of h is 2^h - 1

For any binary tree, if the node with degree 0 is N0 and the node with degree 2 is N2, then N0 = N2 + 1 (mathematical induction)

If the number of layers of the root node is specified to be 1, the depth of a full binary tree with N nodes is log(n + 1) [base 2]

For a complete binary tree with n nodes, if all nodes are numbered from 0 (that is, the structure of the heap) according to the array order from top to bottom and left to right, then for the node with the serial number K: if k>
0 , the serial number of the parent node of k node: (k - 1) / 2;
if k is 0 (root node), then there is no parent node
If 2 k+1<n, the left child's serial number is 2 k+1, and the right child's serial number is 2 k+2 If 2 k+1>n then there is no left child 2*k+2>n then there is no right child

3. Implementation of binary tree chain structure

Binary tree node definition

A node requires a data field, a pointer to the left child node, and a pointer to the right child node.
insert image description here

typedef char BTDataType;

typedef struct BinaryTreeNode
{
    
    
	BTDataType data;
	struct BinaryTreeNode* left;
	struct BinaryTreeNode* right;
}BTNode;

Create a binary tree node

We only need to pass the data of the binary tree nodes, and the dynamically created node space is accepted by the return value.
malloc a node space, give function parameters to data, make left and right point to NULL, and return the address of the space

insert image description here

//创建二叉树的节点
BTNode* BuyBinaryTreeNode(BTDataType x)
{
    
    
	BTNode* root = (BTNode*)malloc(sizeof(BTNode));
	if (root == NULL)
	{
    
    
		perror("malloc:");
		exit(-1);
	}
	root->data = x;
	root->left = root->right = NULL;

	return root;
}

In order to facilitate our understanding, here we first manually create a binary tree to explain related operations, and finally explain the creation of a binary tree in order.

void test()
{
    
    
	BTNode* a = BuyBinaryTreeNode('A');
	BTNode* b = BuyBinaryTreeNode('B');
	BTNode* c = BuyBinaryTreeNode('C');
	BTNode* d = BuyBinaryTreeNode('D');
	BTNode* e = BuyBinaryTreeNode('E');
	BTNode* f = BuyBinaryTreeNode('F');
	BTNode* g = BuyBinaryTreeNode('G');
	BTNode* h = BuyBinaryTreeNode('H');

	a->left = b;
	b->left = d;
	b->right = e;
	e->right = h;
	a->right = c;
	c->left = f;
	c->right = g;
}

The created binary tree is shown in the figure below:
insert image description here

traverse binary tree

There are several ways to traverse a binary tree:

  • Preorder traversal: root node -> left subtree -> right subtree
  • Inorder traversal: left subtree -> root node -> right subtree
  • Post-order traversal: left subtree -> right subtree -> root node
  • Layer order traversal: from left to right and from top to bottom, traverse the binary tree nodes in turn

Preorder traversal of the binary tree (BinaryTreePrevOrder)

For the binary tree in the figure below, the result of the pre-order traversal is: ABD##E#H##CF##G## ('#' means NULL)
insert image description here
, so how is it traversed? We need to recurse the binary tree in the order of root, left, and right.
insert image description here

//二叉树前序遍历   根节点 左子树  右子树
void BinaryTreePrevOrder(BTNode* root)
{
    
    
	if (root == NULL)
	{
    
    
		printf("# ");
		return;
	}

	//根节点
	printf("%c ", root->data);
	//左子树
	BinaryTreePrevOrder(root->left);
	//右子树
	BinaryTreePrevOrder(root->right);
}

How does this code unfold?
insert image description here

Inorder traversal of a binary tree (BinaryTreeInOrder)

The in-order traversal is similar to the pre-order traversal, only the access of the root node and the left subtree recursively exchange the execution order. For the binary tree in the
figure below, the result of the in-order traversal is: #D#B#E#H#A#F #C#G# ( ' # ' means NULL )
insert image description here
insert image description here

//二叉树中序遍历		左子树  根  右子树
void BinaryTreeInOrder(BTNode* root)
{
    
    
	if (root == NULL)
	{
    
    
		printf("# ");
		return;
	}

	//左子树
	BinaryTreeInOrder(root->left);
	//根
	printf("%c ", root->data);
	//右子树
	BinaryTreeInOrder(root->right);
}

Post-order traversal of the binary tree (BinaryTreePostOrder)

Post-order traversal is to adjust the access order of the root node again, and adjust the access order of the root node to the recursion of the left subtree and the recursion of the right subtree.

For the binary tree in the figure below, the order traversal result is: ##D###HEB##F##GCA ('#' means NULL)
insert image description here
insert image description here

//二叉树后序遍历  左子树 右子树 根
void BinaryTreePostOrder(BTNode* root)
{
    
    
	if (root == NULL)
	{
    
    
		printf("# ");
		return;
	}

	//左子树
	BinaryTreePostOrder(root->left);
	//右子树
	BinaryTreePostOrder(root->right);
	//根
	printf("%c ", root->data);
}

Level order traversal of binary tree (BinaryTreeLevelOrder)

To implement the level-order traversal of a binary tree, we need the help of a queue.
We put the root node into the queue first, and then every time we output the queue head data, the left child node and the right child node pointed to by the queue head data are respectively put into the queue. If the left child node or the right child node is NULL, it will not be queued. Repeat the above process until the queue is empty

insert image description here

//层序遍历  借助队列  出队头数据时,将其左子节点 与 右子节点依次入队列
void BinaryTreeLevelOrder(BTNode* root)
{
    
    
	Quene q;
	QueneInit(&q);

	//入根节点
	QuenePush(&q, root);

	//队列为空,代表二叉树中元素也遍历完成
	while (!QueneEmpty(&q))
	{
    
    
		QDataType val = QueneFront(&q);
			printf("%c ", val->data);

		//入数据  该节点的左节点 与 右节点
		if (val->left != NULL)
			QuenePush(&q, val->left);

		if (val->right != NULL)
			QuenePush(&q, val->right);

		//出队头数据
		QuenePop(&q);
	}
		QueneDestrory(&q);
}

Number of Binary Tree Nodes (BinaryTreeSize)

We use recursive thinking to look at the interface of the number of binary tree nodes.
Subproblems: the number of nodes in the left subtree of the root node and the number of nodes in the right subtree of the root node
End condition: empty nodes are returned,
so the problem of finding the number of binary tree nodes can be converted to the number of nodes in the left subtree of the root node + The number of right subtree nodes of the root node + the total number of nodes of the root node

//二叉树节点个数   根节点的左子树与右子树的节点个数和  
int BinaryTreeSize(BTNode* root)
{
    
    
	if (root == NULL)
	{
    
    
		return 0;
	}

	//        左子树节点数                 右子树节点数               根节点
	return BinaryTreeSize(root->left) + BinaryTreeSize(root->right) + 1;
}

For the recursive expansion graph of the following binary tree:
insert image description here
insert image description here

The number of K-level nodes in the binary tree (BinaryTreeLevelKSize)

Function declaration:

int BinaryTreeLevelKSize(BTNode* root, int k);

Sub-problem: the number of nodes at level K-1 of the left subtree of the root node and the number of nodes at level K-1 of the right subtree of the root node
End condition: access to an empty node or find the number of levels sought (k == 1)

That is to say, the problem of finding the number of nodes at level K of a binary tree is transformed into finding the sum of the number of nodes at level K-1 of the left subtree of the root node and the number of nodes at level K-1 of the right subtree of the root node.

//二叉树第K层节点个数       左子树的第k-1层节点数 + 右子树的第k-1层节点数     不同栈帧的k互不影响
int BinaryTreeLevelKSize(BTNode* root, int k)
{
    
    
	//如果 k 超过数的深度
	if (root == NULL)
		return 0;

	if (k == 1)
		return 1;

	return BinaryTreeLevelKSize(root->left, k - 1) + BinaryTreeLevelKSize(root->right, k - 1);
}

For the following binary tree, find the recursive expansion graph of the number of nodes in the third layer.
insert image description here
insert image description here

The number of binary tree leaf nodes (BinaryTreeLeafSize)

Function declaration:

int BinaryTreeLeafSize(BTNode* root);

Sub-problem: the leaf node of the left subtree of the root node and the leaf node of the right subtree of the root node
End condition: visit to an empty node or visit to a leaf node

The original problem is transformed into the number of leaf nodes in the left subtree of the root node + the number of leaf nodes in the right subtree of the root node.


//二叉树叶子节点个数   左子树的叶子节点 + 右子树的叶子结点
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);
}

For the following binary tree, find the recursive expansion graph of the tree of its leaf nodes
insert image description here
insert image description here

Find the node with the value X in the binary tree (BinaryTreeFind)

Preorder traversal to find the node, if it is the node, return the address of the node directly. If it is not the node, continue to search the left subtree of the node, if the left subtree is not found, search the right subtree.

//二叉树查找值为X的节点   前序遍历查找  
BTNode* BinaryTreeFind(BTNode* root, BTDataType x)
{
    
    
	if (root == NULL)
		return NULL;

	//根
	if (root->data == x)
		return root;

	//左子树
	BTNode* leftNode = BinaryTreeFind(root->left, x);
	if (leftNode != NULL)
		return leftNode;

	//右子树
	BTNode* rightNode = BinaryTreeFind(root->right, x);
	if (rightNode != NULL)
		return rightNode;

	return NULL;
}

For the following binary tree, find the recursive expansion graph of ' C '
insert image description here
insert image description here

Determine whether a binary tree is a complete binary tree (BinaryTreeComplete)

A complete binary tree is also a heap, in which valid data (excluding NULL) is continuous when its level order is traversed.
You only need to use the queue to traverse the binary tree in order (if the left or right child of a node is NULL, it will also be queued). When the data at the head of the queue is NULL, judge whether the subsequent data is all NULL, if the subsequent data is all NULL, return true, if one of the subsequent elements is not NULL, return false.


//完全二叉树的节点是连续的,层序遍历二叉树,如果遇到NULL,检查栈中后续元素是否都为NULL
bool BinaryTreeComplete(BTNode* root)
{
    
    
	Quene q;
	QueneInit(&q);

	QuenePush(&q, root);
	while (!QueneEmpty(&q))
	{
    
    
		BTNode* node = QueneFront(&q);
		QuenePop(&q);

		if (node != NULL)
		{
    
    
			QuenePush(&q, node->left);
			QuenePush(&q, node->right);
		}
		else
		{
    
    
			break;
		}
	}

	while (!QueneEmpty(&q))
	{
    
    
		BTNode* node = QueneFront(&q);
		QuenePop(&q);

		if (node != NULL)
		{
    
    
			QueneDestrory(&q);
			return false;
		}
	}

	QueneDestrory(&q);
	return true;
}

Build a binary tree from an array traversed in preorder

In the array traversed in preorder, we use ' # ' to represent NULL.
Function declaration: where a is the array traversed in advance, n is the number of nodes, and pi is the number of current nodes

BTNode* BinaryTreeCreate(BTDataType* a, int n, int* pi);

Sub-problem: Build left subtree and right subtree
End condition: Encounter '#' in the pre-order traversal array or the number of nodes is greater than n
Create a root node, then traverse the left subtree and right subtree, make the root node point to the left subtree with the right subtree.

//通过前序遍历的数组"ABD##E#H##CF##G##"构建二叉树
BTNode* BinaryTreeCreate(BTDataType* a, int n, int* pi)
{
    
    
	if (*pi >= n  || a[*pi] == '#')
	{
    
    
		(*pi)++;
		return NULL;
	}

	BTNode* newnode = BuyBinaryTreeNode(a[*pi]);
	(*pi)++;

	//左子节点
	BTNode* leftnode = BinaryTreeCreate(a, n, pi);
	newnode->left = leftnode;

	//右子节点
	BTNode* rightnode = BinaryTreeCreate(a, n, pi);
	newnode->right = rightnode;

	return newnode;
}

4. Code display

Binary tree code display

#pragma once

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>
#include <string.h>

typedef char BTDataType;

typedef struct BinaryTreeNode
{
    
    
	BTDataType data;
	struct BinaryTreeNode* left;
	struct BinaryTreeNode* right;
}BTNode;



//通过前序遍历的数组"ABD##E#H##CF##G##"构建二叉树
BTNode* BinaryTreeCreate(BTDataType* a, int n, int* pi);

//二叉树的销毁
void BinaryTreeDestroy(BTNode* root);

//二叉树节点个数
int BinaryTreeSize(BTNode* root);

//二叉树叶子节点个数
int BinaryTreeLeafSize(BTNode* root);

//二叉树第K层节点个数
int BinaryTreeLevelKSize(BTNode* root, int k);

//二叉树查找值为X的节点
BTNode* BinaryTreeFind(BTNode* root, BTDataType x);

//二叉树前序遍历
void BinaryTreePrevOrder(BTNode* root);

//二叉树中序遍历
void BinaryTreeInOrder(BTNode* root);

//二叉树后序遍历
void BinaryTreePostOrder(BTNode* root);

//层序遍历
void BinaryTreeLevelOrder(BTNode* root);

//判断二叉树是否是完全二叉树
bool BinaryTreeComplete(BTNode* root);

//创建二叉树的节点
BTNode* BuyBinaryTreeNode(BTDataType x);

#include "BinaryTree.h"
#include "quene.h"

//创建二叉树的节点
BTNode* BuyBinaryTreeNode(BTDataType x)
{
    
    
	BTNode* root = (BTNode*)malloc(sizeof(BTNode));
	if (root == NULL)
	{
    
    
		perror("malloc:");
		exit(-1);
	}
	root->data = x;
	root->left = root->right = NULL;

	return root;
}

//二叉树前序遍历   根节点 左子树  右子树
void BinaryTreePrevOrder(BTNode* root)
{
    
    
	if (root == NULL)
	{
    
    
		printf("# ");
		return;
	}

	//根节点
	printf("%c ", root->data);
	//左子树
	BinaryTreePrevOrder(root->left);
	//右子树
	BinaryTreePrevOrder(root->right);
}

//二叉树中序遍历		左子树  根  右子树
void BinaryTreeInOrder(BTNode* root)
{
    
    
	if (root == NULL)
	{
    
    
		printf("# ");
		return;
	}

	//左子树
	BinaryTreeInOrder(root->left);
	//根
	printf("%c ", root->data);
	//右子树
	BinaryTreeInOrder(root->right);
}

//二叉树后序遍历  左子树 右子树 根
void BinaryTreePostOrder(BTNode* root)
{
    
    
	if (root == NULL)
	{
    
    
		printf("# ");
		return;
	}

	//左子树
	BinaryTreePostOrder(root->left);
	//右子树
	BinaryTreePostOrder(root->right);
	//根
	printf("%c ", root->data);
}



//二叉树的销毁  后序遍历二叉树 
void BinaryTreeDestroy(BTNode* root)
{
    
    
	if (root == NULL)
	{
    
    
		return;
	}

	//左子树
	BinaryTreeDestroy(root->left);
	//右子树
	BinaryTreeDestroy(root->right);
	//根
	free(root);
}



//二叉树节点个数   根节点的左子树与右子树的节点个数和  
int BinaryTreeSize(BTNode* root)
{
    
    
	if (root == NULL)
	{
    
    
		return 0;
	}

	//        左子树节点数                 右子树节点数               根节点
	return BinaryTreeSize(root->left) + BinaryTreeSize(root->right) + 1;
}



//二叉树叶子节点个数   左子树的叶子节点 + 右子树的叶子结点
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);
}



//二叉树第K层节点个数       左子树的第k层节点数 + 右子树的第k层节点数     不同栈帧的k互不影响
int BinaryTreeLevelKSize(BTNode* root, int k)
{
    
    
	//如果 k 超过数的深度
	if (root == NULL)
		return 0;

	if (k == 1)
		return 1;

	return BinaryTreeLevelKSize(root->left, k - 1) + BinaryTreeLevelKSize(root->right, k - 1);
}




//二叉树查找值为X的节点   前序遍历查找  
BTNode* BinaryTreeFind(BTNode* root, BTDataType x)
{
    
    
	if (root == NULL)
		return NULL;

	//根
	if (root->data == x)
		return root;

	//左子树
	BTNode* leftNode = BinaryTreeFind(root->left, x);
	if (leftNode != NULL)
		return leftNode;

	//右子树
	BTNode* rightNode = BinaryTreeFind(root->right, x);
	if (rightNode != NULL)
		return rightNode;

	return NULL;
}



//层序遍历  借助队列  出队头数据时,将其左子节点 与 右子节点依次入队列
void BinaryTreeLevelOrder(BTNode* root)
{
    
    
	Quene q;
	QueneInit(&q);

	//入根节点
	QuenePush(&q, root);

	//队列为空,代表二叉树中元素也遍历完成
	while (!QueneEmpty(&q))
	{
    
    
		QDataType val = QueneFront(&q);
			printf("%c ", val->data);

		//入数据  该节点的左节点 与 右节点
		if (val->left != NULL)
			QuenePush(&q, val->left);

		if (val->right != NULL)
			QuenePush(&q, val->right);

		//出队头数据
		QuenePop(&q);
	}
		QueneDestrory(&q);
}



//判断二叉树是否是完全二叉树    层序遍历二叉树

//bool BinaryTreeComplete(BTNode* root)
//{
    
    
//	Quene q;
//	QueneInit(&q);
//
//	//如果某个节点的右节点为空,那么之后遍历的节点的左/右节点也应该为空
//	bool flag = false;
//
//	QuenePush(&q, root);
//	while (!QueneEmpty(&q))
//	{
    
    
//		QDataType val = QueneFront(&q);
//
//		if (val->left == NULL && val->right != NULL)
//			return false;
//
//		if (flag == true && (val->left != NULL || val->right != NULL))
//			return false;
//
//		if (val->left != NULL)
//			QuenePush(&q, val->left);
//
//		if (val->right != NULL)
//			QuenePush(&q, val->right);
//		else
//			flag = true;
//
//		QuenePop(&q);
//	}
//
//	return true;
//}

//完全二叉树的节点是连续的,层序遍历二叉树,如果遇到NULL,检查栈中后续元素是否都为NULL
bool BinaryTreeComplete(BTNode* root)
{
    
    
	Quene q;
	QueneInit(&q);

	QuenePush(&q, root);
	while (!QueneEmpty(&q))
	{
    
    
		BTNode* node = QueneFront(&q);
		QuenePop(&q);

		if (node != NULL)
		{
    
    
			QuenePush(&q, node->left);
			QuenePush(&q, node->right);
		}
		else
		{
    
    
			break;
		}
	}

	while (!QueneEmpty(&q))
	{
    
    
		BTNode* node = QueneFront(&q);
		QuenePop(&q);

		if (node != NULL)
		{
    
    
			QueneDestrory(&q);
			return false;
		}
	}

	QueneDestrory(&q);
	return true;
}



//通过前序遍历的数组"ABD##E#H##CF##G##"构建二叉树
BTNode* BinaryTreeCreate(BTDataType* a, int n, int* pi)
{
    
    
	if (*pi >= n  || a[*pi] == '#')
	{
    
    
		(*pi)++;
		return NULL;
	}

	BTNode* newnode = BuyBinaryTreeNode(a[*pi]);
	(*pi)++;

	//左子节点
	BTNode* leftnode = BinaryTreeCreate(a, n, pi);
	newnode->left = leftnode;

	//右子节点
	BTNode* rightnode = BinaryTreeCreate(a, n, pi);
	newnode->right = rightnode;

	return newnode;
}

Queue code display

#include "BinaryTree.h"
#include <assert.h>

//队列 节点结构--树节点
typedef struct QueneNode
{
    
    
	struct BinaryTreeNode* data;
	struct QueneNode* next;
}QueneNode;

typedef struct BinaryTreeNode* QDataType;

//队列 结构
typedef struct Quene
{
    
    
	QueneNode* head;
	QueneNode* tail;
	int size;
}Quene;


//初始化队列
void QueneInit(Quene* q);

//队尾入队列
void QuenePush(Quene* q, QDataType x);

//队头出数据
void QuenePop(Quene* q);

//获取队列头部元素
QDataType QueneFront(Quene* q);

//获取队列队尾元素
QDataType QueneBack(Quene* q);

//获取队列中有效元素个数
int QueneSize(Quene* q);

//检查队列是否为空,如果为空返回ture,如果非空返回false
bool QueneEmpty(Quene* q);

//销毁队列
void QueneDestrory(Quene* q);

#include "quene.h"

//初始化队列
void QueneInit(Quene* q)
{
    
    
	assert(q);

	q->head = q->tail = NULL;
	q->size = 0;
}

//队尾入队列
void QuenePush(Quene* q, QDataType x)
{
    
    
	assert(q);

	QueneNode* newnode = (QueneNode*)malloc(sizeof(QueneNode));
	if (newnode == NULL)
	{
    
    
		perror("malloc");
		exit(-1);
	}
	newnode->next = NULL;
	newnode->data = x;

	//队列为空
	if (QueneEmpty(q) == true)
	{
    
    
		q->head = q->tail = newnode;
	}
	else//队列不为空
	{
    
    
		q->tail->next = newnode;
		q->tail = newnode;
	}

	q->size++;
}



//队头出数据
void QuenePop(Quene* q)
{
    
    
	assert(q);
	//队列为空
	assert(QueneEmpty(q) != true);

	//队列只有一个元素
	if (q->head->next == NULL)
	{
    
    
		free(q->head);
		q->head = q->tail = NULL;
	}
	else//队列中有多个元素
	{
    
    
		QueneNode* next = q->head->next;
		free(q->head);
		q->head = next;
	}

	q->size--;
}


//获取队列头部元素
QDataType QueneFront(Quene* q)
{
    
    
	assert(q);

	return q->head->data;
}


//获取队列队尾元素
QDataType QueneBack(Quene* q)
{
    
    
	assert(q);

	return q->tail->data;
}


//获取队列中有效元素个数
int QueneSize(Quene* q)
{
    
    
	assert(q);

	return q->size;
}


//检查队列是否为空,如果为空返回ture,如果非空返回false
bool QueneEmpty(Quene* q)
{
    
    
	assert(q);

	return q->size == 0;
}


//销毁队列
void QueneDestrory(Quene* q)
{
    
    
	assert(q);

	QueneNode* cur = q->head;
	while (cur)
	{
    
    
		QueneNode* next = cur->next;
		free(cur);
		cur = next;
	}

}

Summarize

The above is my understanding of binary trees! ! !
insert image description here

Guess you like

Origin blog.csdn.net/li209779/article/details/132343492