Directorio de artículos
1. recorrido del árbol binario
Los nodos del árbol binario en todos los códigos siguientes:
typedef char BTDataType;
//二叉树结点结构体
typedef struct BinaryTreeNode
{
BTDataType data;
struct BinaryTreeNode* left;
struct BinaryTreeNode* right;
}BTNode;
1. Recorrido de reserva
Los recorridos de orden previo, medio y posterior se pueden resolver utilizando la idea de recursividad de divide y vencerás, y el nodo raíz y sus nodos secundarios se procesan por separado.
// 二叉树前序遍历
void BinaryTreePrevOrder(BTNode* root)
{
if (root == NULL)
{
printf("NULL ");
return;
}
printf("%c ", root->data);
BinaryTreePrevOrder(root->left);
BinaryTreePrevOrder(root->right);
}
Aquí solo utilizamos el gráfico de expansión recursiva para analizar el recorrido del pedido previo, y se utiliza la misma idea en orden y postorden:
2. Recorrido en orden
// 二叉树中序遍历
void BinaryTreeInOrder(BTNode* root)
{
if (root == NULL)
{
printf("NULL ");
return;
}
BinaryTreeInOrder(root->left);
printf("%c ", root->data);
BinaryTreeInOrder(root->right);
}
3. Recorrido posterior al pedido
// 二叉树后序遍历
void BinaryTreePostOrder(BTNode* root)
{
if (root == NULL)
{
printf("NULL ");
return;
}
BinaryTreePostOrder(root->left);
BinaryTreePostOrder(root->right);
printf("%c ", root->data);
}
4. Recorrido secuencial de capas
El recorrido del orden de nivel debe realizarse mediante una cola. Si el árbol binario y el nodo no están vacíos, dejemos queponer en cola un puntero a él, luego registre el nodo principal de la cola, imprima su valor primero, luego juzgue que sus hijos izquierdo y derecho no están vacíos y luego únase a la cola, luego elimine el encabezado de la cola y reemplácelo con el siguiente para continuar grabando e imprimiendo... hasta que la cola esté vacía y se complete el recorrido.
Por ejemplo, considere este árbol binario como se muestra:
El resultado del recorrido de la secuencia de capas es: 12345.
Primero, coloque el nodo raíz 1 en la cola e imprima 1
Luego agregue los niños izquierdo y derecho 2 y 3 de 1 al equipo.
Elimine el encabezado de la cola 1, reemplace el frente con 2 e imprima 2
Luego agregue el niño izquierdo 4 de 2 al equipo.
Elimine el encabezado 2, reemplace el frente con 3 e imprima 3
Luego agregue al niño correcto 5 de 3 al equipo.
……
Luego imprima 4 y 5 así para completar el recorrido de orden de nivel del árbol binario.
El código del programa utiliza la cola creada por él mismo, el código es el siguiente:
//层序遍历
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. Número y altura de los nodos del árbol binario.
1. Número de nodos del árbol binario
Se implementa de forma recursiva utilizando el método divide y vencerás. Cuando el nodo raíz está vacío, el valor de retorno es 0. Si no está vacío, devuelve el número de nodos en los subárboles izquierdo y derecho más 1.
int BinaryTreeSize(BTNode* root)
{
return root == NULL ? 0 : BinaryTreeSize(root->left) + BinaryTreeSize(root->right) + 1;
}
2. Número de nodos hoja del árbol binario
Se implementa de forma recursiva utilizando el método divide y vencerás. Cuando el nodo raíz está vacío, se devuelve 0. Cuando el nodo raíz no tiene nodos secundarios, significa que es un nodo hoja y se devuelve 1. En otros casos, simplemente agregue los nodos hoja en los subárboles izquierdo y derecho.
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. Número de nodos en el k-ésimo nivel del árbol binario
Debe asegurarse de que k sea mayor que 0. Cuando el nodo raíz está vacío, se devuelve 0. Cuando k es igual a 1, solo hay un nodo en una capa y se devuelve 1. Cuando k>1, el número de nodos en la k-ésima capa es equivalente al k-ésimo hijo de sus hijos izquierdo y derecho. -Se suma el número de nodos en la capa 1.
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. Encuentra el nodo con valor x en un árbol binario.
Si el siguiente nodo está vacío, se devuelve NULL si no se puede encontrar. Cuando el valor del nodo raíz es el valor que está buscando, se devuelve el nodo. Si no son iguales, se juzgan sus nodos secundarios izquierdo y derecho. respectivamente hasta que los encuentren.
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. Creación y destrucción de árboles binarios.
1. Cree un árbol binario atravesando la matriz en orden anticipado.
Lea una cadena transversal de pedido anticipado ingresada por el usuario y cree un árbol binario (almacenado como un puntero) basado en esta cadena. Por ejemplo, la siguiente cadena transversal de pedido anticipado: ABC##DE#G##F### donde "#" representa un espacio y el carácter de espacio representa un árbol vacío. Después de establecer el árbol binario, realice un recorrido en orden en el árbol binario y genere los resultados del recorrido.
#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. Destrucción de árboles binarios
void BinaryTreeDestory(BTNode* root)
{
if (root == NULL)
{
return;
}
BinaryTreeDestory(root->left);
BinaryTreeDestory(root->right);
free(root);
}
3. Determinar si es un árbol binario completo.
Modifique el recorrido de orden de nivel del árbol binario para que los nodos vacíos también ingresen a la cola. Al atravesar un nodo vacío, saldrá. Si hay nodos no vacíos antes del final del recorrido, no es un árbol binario completo.
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. Código de prueba
Cree manualmente un árbol binario como se muestra a continuación y pruebe el código:
el resultado de la prueba debe ser:
Preorden: 123874569
Secuencia intermedia: 832715469
Postorden: 837259641
Si es un árbol binario completo: 0
Número de nodos: 9
Número de nodos hoja: 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;
}
resultado de la operación:
Los resultados de ejecución son consistentes con los resultados previstos.