Recorrido del árbol binario + ejercicios básicos

El árbol binario completo anterior es adecuado para el almacenamiento de datos, y debido a que se almacena de forma continua en la memoria, se implementa con una tabla de secuencias y se introducen los problemas de clasificación de montones y TOP-K.

Hoy aprendemos sobre el problema transversal del árbol binario y completamos varios ejercicios básicos del árbol binario.


contenido

recorrido del árbol binario

Hacer un pedido

Orden de acceso:

Icono:

 secuencia intermedia

Orden de acceso:

Icono:

orden de publicación

Orden de acceso:

Icono:

Construya manualmente un árbol binario encadenado 

definición

 crear nodo

Crear un árbol binario 

recorrido de pedido anticipado

Recorrido en orden

 recorrido posterior al pedido

Ejercicio

Buscar árbol de nodos de árbol binario

Encuentre la cantidad de nodos secundarios en un árbol binario 

El número de nodos en la capa k-ésima 

Profundidad del árbol binario

Árbol binario encontrar nodo con valor x


recorrido del árbol binario

El recorrido del árbol binario incluye: estructura recursiva recorrido de preorder/inorder/postorder:

1. Recorrido en orden previo (también conocido como recorrido en orden previo): la operación de visitar el nodo raíz ocurre antes de atravesar sus subárboles izquierdo y derecho.
2. Recorrido en orden: la operación de visitar el nodo raíz ocurre entre atravesar sus subárboles izquierdo y derecho.
3. Recorrido posterior al orden: la operación de visitar el nodo raíz se produce después de recorrer sus subárboles izquierdo y derecho.

Tome el siguiente árbol binario como ejemplo, realice un recorrido en preorden, en orden y en orden posterior:

Hacer un pedido

Análisis: a partir del nodo raíz, primero visite la raíz, luego visite el subárbol izquierdo (el nodo raíz se visita primero en el subárbol izquierdo, luego se visita el subárbol izquierdo y el subárbol derecho), y finalmente se visita el subárbol derecho (Primero se visita el nodo raíz y luego se visita el subárbol izquierdo, el subárbol izquierdo y el subárbol derecho)

Orden de acceso:

Primero visite la raíz del árbol 1 y luego visite el subárbol izquierdo L1 del árbol:

Visite la raíz 2 de L1 y luego visite su subárbol izquierdo Ll2:

Visite Ll2 root 3, y luego visite su subárbol izquierdo: si el subárbol izquierdo está vacío, visite su subárbol derecho, si el subárbol derecho está vacío, regrese al subárbol anterior L1;

En este punto, se completa el acceso del subárbol izquierdo de L1, y se accede al subárbol derecho de L1 a NULL, y si está vacío, se devuelve el árbol anterior;

En este punto, se accede a la raíz del árbol y al subárbol izquierdo, y se accede al subárbol derecho R1 del árbol:

Visite la raíz 4 de R1 y luego visite el subárbol izquierdo Rl1 de R1:

Acceda a la raíz 5 de Rl1, luego acceda al subárbol izquierdo y al subárbol derecho NULL de Rl1, y regrese al árbol anterior R1;

En este punto, se accede al subárbol izquierdo Rl1 de R1, y luego se accede al subárbol derecho Rr1 de R1:

Acceda a la raíz 6 de Rr1, luego acceda a los subárboles izquierdo y derecho de Rr1 NULL y regrese al árbol anterior R1;

En este punto, se accede a la raíz de R1 y a los subárboles izquierdo y derecho, y se devuelve el árbol anterior;

En este punto, se visitan la raíz y el subárbol izquierdo del árbol, y se visita todo el árbol.

Icono:

 secuencia intermedia

Análisis: visite primero el subárbol izquierdo, visite el nodo raíz después de visitar el subárbol izquierdo y visite el subárbol derecho después de visitar el nodo raíz. El subárbol izquierdo y el subárbol derecho también visitan primero el subárbol izquierdo, luego la raíz y finalmente el subárbol derecho .

Orden de acceso:

Comenzando desde la raíz del árbol, visite primero su subárbol izquierdo L1:

El subárbol izquierdo L1 no está vacío, visite el subárbol izquierdo Ll2 de L1:

El subárbol izquierdo Ll2 no está vacío, visite el subárbol izquierdo de Ll2:

Si el subárbol izquierdo está vacío, visite la raíz 3 de Ll2, luego visite el nodo derecho de Ll2, si el nodo derecho está vacío, regrese al subárbol L1;

Después de acceder al subárbol izquierdo del subárbol L1, visite la raíz 2 de L1 y luego visite el subárbol derecho de L1, si está vacío, regrese al árbol árbol;

Después de acceder al subárbol izquierdo del árbol, visite la raíz 1 del árbol y luego visite el subárbol derecho R1 del árbol:

El subárbol derecho R1 no está vacío, visite el subárbol izquierdo Rl1 de R1:

Rl1 no está vacío, visite el subárbol izquierdo de Rl1, el subárbol izquierdo está vacío, visite la raíz 5 de Rl1 y luego visite su subárbol derecho:

Si el subárbol derecho está vacío, regresa al árbol anterior R1;

Después de visitar el subárbol izquierdo de R1, visite su raíz 4 y luego visite su subárbol derecho Rr1:

Rr1 no está vacío, visite su subárbol izquierdo, el subárbol izquierdo está vacío, visite Rr1 root 6, y luego visite su subárbol derecho está vacío, devuelva R1;

En este punto, se visitan el subárbol izquierdo, la raíz y el subárbol derecho del árbol.

Icono:

orden de publicación

Análisis: primero visite el subárbol izquierdo (el subárbol izquierdo también es el subárbol izquierdo, el subárbol derecho, la raíz), luego visite el subárbol derecho (el subárbol derecho también es el subárbol izquierdo, el subárbol derecho, la raíz) y finalmente visite el nodo raíz .

Orden de acceso:

Primero visite el árbol, si no está vacío, visite su subárbol izquierdo L1, si L1 no está vacío, visite su subárbol izquierdo Ll2;

Ll2 no está vacío, visita su subárbol izquierdo, está vacío, visita su subárbol derecho, está vacío, visita su raíz 3, vuelve al árbol anterior L1;

Después de acceder al subárbol izquierdo de L1, visite su subárbol derecho, está vacío, visite su raíz 2, regrese al árbol anterior;

Después de acceder al subárbol izquierdo del árbol, acceda a su subárbol derecho R1, si R1 no está vacío, acceda a su subárbol izquierdo Rl1;

Rl1 no está vacío, visita su subárbol izquierdo, está vacío, visita su subárbol derecho, si está vacío, visita su raíz 5, vuelve al árbol anterior R1;

Después de acceder al subárbol izquierdo de R1, visite su subárbol derecho Rr1, si Rr1 no está vacío, visite su subárbol izquierdo;

El subárbol izquierdo de Rr1 está vacío, visite su subárbol derecho, si está vacío, visite su raíz 6 y regrese al árbol anterior R1;

En este punto, se completa el acceso al subárbol derecho del subárbol izquierdo de R1, se accede a su raíz 4 y se vuelve a colocar el árbol anterior;

En este momento, se visitan los subárboles izquierdo y derecho del árbol, y se visita su raíz 1; se visita todo el árbol.

Icono:

Construya manualmente un árbol binario encadenado 

No es difícil encontrar que el recorrido antes mencionado siempre volverá al árbol anterior en el medio. Se ha utilizado la idea recursiva. Aquí implementamos manualmente un árbol binario encadenado simple para completar nuestro pedido anticipado, en orden, y recorrido posterior a la orden.

definición

Defina que cada nodo consta de datos, dirección del subárbol izquierdo y dirección del subárbol derecho

typedef int BTDataType;
typedef struct BinaryTreeNode
{
	BTDataType data;  //数据
	struct BinaryTreeNode* left;   //左子树地址
	struct BinaryTreeNode* right;  //右子树地址
}BTNode;

 crear nodo

Coloque los datos fijos en el nodo creado y deje vacíos los punteros del subárbol izquierdo y derecho.

BTNode* BuyNode(BTDataType x)
{
	BTNode* root = (BTNode*)malloc(sizeof(BTNode));
	root->data = x;
	root->left = NULL;
	root->right = NULL;
	return root;
}

Crear un árbol binario 

Cree nodos manualmente y apunte los punteros del subárbol izquierdo y derecho a posiciones fijas.Tome el árbol binario anterior como ejemplo:

//手动创建
BTNode* CreatBinaryTree()
{
	BTNode* node1 = BuyNode(1);
	BTNode* node2 = BuyNode(2);
	BTNode* node3 = BuyNode(3);
	BTNode* node4 = BuyNode(4);
	BTNode* node5 = BuyNode(5);
	BTNode* node6 = BuyNode(6);
	node1->left = node2;
	node1->right = node4;
	node2->left = node3;
	node4->left = node5;
	node4->right = node6;
	return node1;
}

recorrido de pedido anticipado

De acuerdo con nuestro análisis del orden del recorrido de preorden: raíz, subárbol izquierdo, subárbol derecho, escriba el código de preorden:

// 二叉树前序遍历
void PreOrder(BTNode* root)
{
	if (root==NULL)
	{
		return;
	}
	printf("%d ",root->data);
	PreOrder(root->left);
	PreOrder(root->right);
}

Recorrido en orden

// 二叉树中序遍历
void InOrder(BTNode* root)
{
	if (root == NULL)
	{
		return;
	}
	InOrder(root->left);
	printf("%d ", root->data);
	InOrder(root->right);
}

 recorrido posterior al pedido

// 二叉树后序遍历
void PostOrder(BTNode* root)
{
	if (root == NULL)
	{
		return;
	}
	PostOrder(root->left);
	PostOrder(root->right);
	printf("%d ", root->data);
}

Ejercicio

Buscar árbol de nodos de árbol binario

Método 1: agregue una variable de conteo en el pedido previo, en el pedido y posterior (la variable es global o estática para evitar que el conteo se restablezca durante la recursividad)

Desventaja: el conteo se acumulará cuando se llame repetidamente, y el conteo debe restablecerse a 0 cada vez que se llame;

//定义全局或者静态变量
//多次调用会累加
int count = 0;
int BTreeSize(BTNode* root)
{
	if (root == NULL)
		return;
	++count;
	BTreeSize(root->left);
	BTreeSize(root->right);
	return  count;
}

Método 2: atravesar + contar (pasar la dirección transversal al atravesar)

//遍历+计数
//将变量地址传过去,计数---思想最优
void BTreeSize(BTNode* root,int* count)
{
	if (root == NULL)
		return;
	++(*count);
	BTreeSize(root->left,count);
	BTreeSize(root->right,count);
}

Método 3: Recursividad - Pensamiento divide y vencerás

Cuando la raíz está vacía, devuelve 0, el número de nodos del subárbol izquierdo + el número de nodos del subárbol derecho + 1 (el propio nodo raíz)

//递归--分治思想--节点个数
int BTreeSize(BTNode* root)
{
	return root == NULL ? 0 : BTreeSize(root->left) + BTreeSize(root->right) + 1;
}

Encuentre la cantidad de nodos secundarios en un árbol binario 

Número de nodos secundarios en el árbol binario = número de nodos en el subárbol izquierdo + número de nodos en el subárbol derecho

Nodo hoja: nodo cuyo subárbol izquierdo y subárbol derecho están vacíos

//叶子节点个数
int BTreeLeafSize(BTNode* root)
{
	if (root==NULL)
	{
		return 0;
	}
	if (root->left == NULL&&root->right==NULL)
	{
		return 1;
	}
	return BTreeLeafSize(root->left) + BTreeLeafSize(root->right);
}

El número de nodos en la capa k-ésima 

 Encuentre el número de nodos en el tercer nivel del árbol.

Es decir, la suma de los nodos de la segunda capa de L1 y R1

Es decir, la suma de los nodos de la primera capa de Ll1, Rl1 y Rr1

Cuando k=1, solo devuelve 1

//第k层节点个数
int BTreeLeveSize(BTNode* root,int k)
{
	assert(k>=1);
	if (root==NULL)
	{
		return 0;
	}
	if (k == 1)
	{
		return 1;
	}
	return BTreeLeveSize(root->left, k - 1) + BTreeLeveSize(root->right, k - 1);

Profundidad del árbol binario

Profundidad del árbol binario = profundidad máxima del subárbol izquierdo y el subárbol derecho + 1

Necesita comparar la altura de los subárboles izquierdo y derecho para determinar cuál devolver

//二叉树深度
int BTreeDepth(BTNode* root)
{
	if (root==NULL)
	{
		return 0;
	}
	int leftdepth = BTreeDepth(root->left);
	int rightdepth = BTreeDepth(root->right);
	return leftdepth >rightdepth ? leftdepth + 1 : rightdepth + 1;
}

Árbol binario encontrar nodo con valor x

Determine si la raíz es el nodo que está buscando y, de ser así, devuelva la dirección del nodo

De lo contrario, vaya al subárbol izquierdo para encontrar, busque la dirección del nodo de retorno y regrese vacío si no se encuentra

Luego ingrese el subárbol derecho para buscar, encuentre la dirección del nodo de retorno y regrese vacío si no se encuentra

// 二叉树查找值为x的节点
BTNode* BinaryTreeFind(BTNode* root, BTDataType x)
{
	if (root==NULL)
	{
		return NULL;
	}
	if (root->data == x)
		return root;
	if (BinaryTreeFind(root->left, x))
		return BinaryTreeFind(root->left,x);
	if (BinaryTreeFind(root->right, x))
		return BinaryTreeFind(root->right, x);
	return NULL;
}

Supongo que te gusta

Origin blog.csdn.net/weixin_53316121/article/details/124155945
Recomendado
Clasificación