Estructura de datos Código C 6.1: Construcción y recorrido del árbol binario

Objetivos de aprendizaje: aprender a construir y atravesar árboles binarios

Guía de estudio: Código de Fanshen

Tareas de aprendizaje:

  1. copiar codigo
  2. Catálogo de resultados de aprendizaje

    1 código completo

    2 resultados de la prueba

    3 gráfico

Descripción del código:

  1. El recorrido profundo del árbol binario usa una pila, por lo que el código es muy conciso. El método sin usar la pila tiene la estructura de datos de código correspondiente Código C 6.x: Construya una pila usted mismo para realizar el recorrido del árbol binario .
  2. Las colas se utilizan para el recorrido jerárquico. Esta vez, asignamos deliberadamente menos espacio para ver si la cola circular puede reutilizar el espacio normalmente.
  3. Una pila también se usa para construir un árbol binario a partir de una cadena. El almacenamiento no comprimido del árbol binario también se puede ver aquí.
  4. El árbol binario es un tipo importante de estructura de árbol. La estructura de datos abstraída de muchos problemas prácticos a menudo tiene la forma de un árbol binario.Incluso un árbol general se puede convertir fácilmente en un árbol binario, y la estructura de almacenamiento y el algoritmo del árbol binario son relativamente simples, por lo que el árbol binario es particularmente importante. La característica de un árbol binario es que cada nodo solo puede tener como máximo dos subárboles, y hay puntos izquierdo y derecho. Un árbol binario es una colección de n elementos finitos. La colección está vacía o consta de un elemento llamado raíz y dos árboles binarios disjuntos llamados subárbol izquierdo y subárbol derecho respectivamente. Es un árbol ordenado. Cuando el conjunto está vacío, el árbol binario se denomina árbol binario vacío. En un árbol binario, un elemento también se denomina nodo.
  5. Recorrido de orden frontal, medio y posterior agregado manualmente (prefiero usar la recursividad).

tiempo de estudio:

2022.5.24

1 código completo

#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 resultados de la prueba

---- 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 gráfico

Recorrido de orden de capas: coloque en capas el árbol binario y luego recorra cada capa de izquierda a derecha

Supongo que te gusta

Origin blog.csdn.net/qq_61649579/article/details/124952433
Recomendado
Clasificación