Data structure C code 6.1: Construction and traversal of binary tree

Learning objectives: learn to build and traverse binary trees

Study Guide: Fanshen's Code

Learning tasks:

  1. copy code
  2. Learning Outcome Catalog

    1 full code

    2 test results

    3 graphic

Code description:

  1. The depth traversal of the binary tree uses a stack, so the code is very concise. The method without using the stack has the corresponding code data structure C code 6.x: build a stack by yourself to realize the binary tree traversal .
  2. Queues are used for hierarchical traversal. This time, we deliberately allocate less space to see if the circular queue can reuse space normally.
  3. A stack is also used to construct a binary tree from a string. The non-compressed storage of the binary tree can also be seen here.
  4. Binary tree is an important type of tree structure. The data structure abstracted from many practical problems is often in the form of a binary tree. Even a general tree can be easily converted into a binary tree, and the storage structure and algorithm of the binary tree are relatively simple, so the binary tree is particularly important. The characteristic of a binary tree is that each node can only have at most two subtrees, and there are left and right points. A binary tree is a collection of n finite elements. The collection is either empty or consists of an element called the root and two disjoint binary trees called the left subtree and the right subtree respectively. It is an ordered tree. When the set is empty, the binary tree is called an empty binary tree. In a binary tree, an element is also called a node.
  5. Manually added front, middle and back order traversal (I prefer to use recursion).

study-time:

2022.5.24

1 full code

#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>

#define MAXSIZE 5

//二叉树的结构 
typedef struct BTnode
{
	char element;
	struct BTnode *left;
	struct BTnode *right;	
}*BTnodePtr;
//队列
typedef struct BTNodePtrQueue
{
	BTnodePtr *nodePtrs;
	int front;
	int rear;
}*QueuePtr;
/**
 * @brief 初始化队列
 * 
 * @return 
 */
QueuePtr initQueue()
{
	QueuePtr resultPtr = (QueuePtr)malloc(sizeof(struct BTNodePtrQueue));
	resultPtr->nodePtrs = (BTnodePtr*)malloc(MAXSIZE * (sizeof(BTnodePtr)));
	resultPtr->front = 0;
	resultPtr->rear = 1;
	return resultPtr;	
} 
/**
 * @brief 判断是否为空队列
 * 
 * @param paraQueuePtr 
 * 
 * @return 
 */
int isQueueEmpty(QueuePtr paraQueuePtr)
{
	if ((paraQueuePtr->front + 1) % MAXSIZE == paraQueuePtr->rear) 
	{
		return 1;
	}
	
	return 0;
}
/**
 * @brief 添加节点
 * 
 * @param Queue 
 * @param newBTnodePtr 
 */
void enqueue(QueuePtr Queue,BTnodePtr newBTnodePtr)
{
	if((Queue->rear +1)%MAXSIZE == (Queue->front)%MAXSIZE )
	{
		printf("错误,队满,无法添加节点.\n");
		return ; 
	}	
	Queue->nodePtrs [Queue->rear] = newBTnodePtr;
	Queue->rear = (Queue->rear+1)%MAXSIZE;
	printf("添加 节点%c 成功.\n", newBTnodePtr->element);
	
} 
/**
 * @brief 删除节点
 * 
 * @param Queue 
 * 
 * @return 
 */
BTnodePtr deQueue(QueuePtr Queue)
{
	if(isQueueEmpty(Queue))
	{
		printf("错误,队空,无法删除节点.\n");
		return Queue->nodePtrs [Queue->front];
	}
	Queue->front = (Queue->front +1)%MAXSIZE;
	printf("删除 节点%c 成功.\n",Queue->nodePtrs [Queue->front]->element);
	
	return  Queue->nodePtrs [Queue->front];
} 
/**
 * @brief 创建并初始化结点 
 * 
 * @param newElement 
 * 
 * @return 
 */
BTnodePtr constructBTnode(char newElement)
{
	BTnodePtr newPtr = (BTnodePtr)malloc(sizeof(struct BTnode));
	newPtr->element = newElement;
	newPtr->left = NULL;
	newPtr->right  = NULL;
	return newPtr;
}
/**
 * @brief 创建并初始化二叉树
 * 
 * @param newString 
 * 
 * @return 
 */
BTnodePtr stringToBTree(char *newString)
{
	int i=0;
	char ch;
	
	//使用队列管理指针
	QueuePtr Queue = initQueue();
	
	BTnodePtr resultHeader;//根
	BTnodePtr tempParent,tempLeftChlid,tempRightChild;
	
	ch = newString[i];
	resultHeader = constructBTnode(ch);
	enqueue(Queue,resultHeader);
	
	while(!isQueueEmpty(Queue))
	{
		tempParent = deQueue(Queue);
		//左子节点
		i++;
		if(newString[i] == '#')
		{
			tempParent->left = NULL;
		}
		else
		{
			tempLeftChlid = constructBTnode(newString[i]);
			enqueue(Queue,tempLeftChlid);
			tempParent->left = tempLeftChlid;
		}
		//右子节点
		i++;
		if(newString[i] == '#')
		{
			tempParent->right = NULL;
		}
		else
		{
			tempRightChild = constructBTnode(newString[i]);
			enqueue(Queue,tempRightChild);
			tempParent->right = tempRightChild;
		}
		
	} 
	//返回根节点
	return resultHeader;	
}
/**
 * @brief 层序遍历
 * 
 * @param newTreePtr 
 */
void levelwise(BTnodePtr newTreePtr)
{
	char string[100];
	int i = 0;
	//使用队列管理指针
	QueuePtr Queue = initQueue();
	BTnodePtr tempNodePtr;
	
	enqueue(Queue,newTreePtr);
	while(!isQueueEmpty(Queue))
	{
		tempNodePtr = deQueue(Queue);
		string[i] = tempNodePtr->element ;
		i++;
		if(tempNodePtr->left != NULL)
		{
			enqueue(Queue,tempNodePtr->left);
		}
		if(tempNodePtr->right  != NULL)
		{
			enqueue(Queue,tempNodePtr->right);
		}
	}
	string[i] = '\0';
	printf("层序遍历:%s\n",string);
} 
/**
 * @brief 前序遍历二叉树
 * 
 * @param newTreePtr 
 * 
 * @return 
 */
int preVisitBiTree(BTnodePtr newTreePtr)
{
	if(newTreePtr)
	{
		/* 先遍历根节点 */
		printf("%c",newTreePtr->element);
		
		/* 遍历左子树 */
		preVisitBiTree(newTreePtr->left);
		
		/* 遍历右子树 */
		preVisitBiTree(newTreePtr->right);
		
	}
	return 0;
}
/**
 * @brief 中序遍历二叉树
 * 
 * @param newTreePtr 
 * 
 * @return 
 */
int inVisitBiTree(BTnodePtr newTreePtr)
{
	if(newTreePtr)
	{
		/* 遍历左子树 */
		preVisitBiTree(newTreePtr->left);
		
		
		/* 先遍历根节点 */
		printf("%c",newTreePtr->element);
		
		/* 遍历右子树 */
		preVisitBiTree(newTreePtr->right);
		
	}
	return 0;
}
/**
 * @brief 后序遍历二叉树
 * 
 * @param newTreePtr 
 * 
 * @return 
 */
int postVisitBiTree(BTnodePtr newTreePtr)
{
	if(newTreePtr)
	{
		/* 遍历左子树 */
		preVisitBiTree(newTreePtr->left);
		
		
		/* 遍历右子树 */
		preVisitBiTree(newTreePtr->right);
		
		
		/* 先遍历根节点 */
		printf("%c",newTreePtr->element);
		
	}
	return 0;
}

void BinaryTreeTest(){
	printf("---- BinaryTreeTest 测试开始 ----\n");
	printf("初始化二叉树\n");
	BTnodePtr tempHeader;
	char* tempString = "acde#bf######";
	tempHeader = stringToBTree(tempString);
	printf("进行层序遍历\n");
	levelwise(tempHeader);
	printf("\n前序遍历:");
	preVisitBiTree(tempHeader);
	printf("\n中序遍历:");
	inVisitBiTree(tempHeader);
	printf("\n后序遍历:");
	postVisitBiTree(tempHeader);
	printf("\n");
	printf("---- BinaryTreeTest 测试结束 ----\n");
}

int main(){
	BinaryTreeTest();
	return 1;
}

2 test results

---- BinaryTreeTest 测试开始 ----
初始化二叉树
添加 节点a 成功.
删除 节点a 成功.
添加 节点c 成功.
添加 节点d 成功.
删除 节点c 成功.
添加 节点e 成功.
删除 节点d 成功.
添加 节点b 成功.
添加 节点f 成功.
删除 节点e 成功.
删除 节点b 成功.
删除 节点f 成功.
进行层序遍历
添加 节点a 成功.
删除 节点a 成功.
添加 节点c 成功.
添加 节点d 成功.
删除 节点c 成功.
添加 节点e 成功.
删除 节点d 成功.
添加 节点b 成功.
添加 节点f 成功.
删除 节点e 成功.
删除 节点b 成功.
删除 节点f 成功.
层序遍历:acdebf

前序遍历:acedbf
中序遍历:ceadbf
后序遍历:cedbfa
---- BinaryTreeTest 测试结束 ----

3 graphic

Layer order traversal: layer the binary tree, and then traverse each layer from left to right

Guess you like

Origin blog.csdn.net/qq_61649579/article/details/124952433