"Estructura básica de datos" para comenzar con el árbol binario desde velocidad cero

"Sword Qi tiene 30,000 millas de ancho, y la luz de una espada es fría en diecinueve continentes"

contenido

1. El enfoque de este capítulo

2. árbol

2.1 El concepto de árbol

2.2 Conocimientos básicos sobre los árboles

3. Árbol binario

3.1 El concepto de árbol binario

3.2 Árbol binario especial

3.2.1 Árbol binario completo

 3.2.2 Árbol binario completo

 3.3 Propiedades de los árboles binarios

3.4 Ejercicios sobre preguntas de opción múltiple relacionadas con las propiedades de los árboles binarios

3.5 Implementación de la estructura de cadena de árbol binario

3.5.1 Recorrido de la estructura de cadena de árbol binario

3.5.2 Entrenamiento de opción múltiple

4. Recursividad

4.1 El concepto de recursividad

4.2 El significado central de la recursividad

4.3 ¿Cómo escribir una recursividad?

​Práctica de preguntas comunes de OJ de cinco

5.1 Recorrido de pedido anticipado del árbol binario (Likou)

5.2 La profundidad máxima del árbol binario (fuerza de hebilla)

5.3 Árbol binario equilibrado (fuerza de hebilla)


1. El enfoque de este capítulo

  1. Introducir el concepto de árboles.
  2. Introducir el concepto de árbol binario.
  3. Domina los fundamentos de la recursividad
  4. do preguntas y explicación detallada del árbol binario

2. árbol

2.1 El concepto de árbol

Un árbol es un conjunto finito T de n nodos. Cuando n=0, se llama árbol vacío; cuando n>0, el conjunto satisface las siguientes condiciones:

​ ①Debe existir un nodo llamado raíz (root), que no tiene antecesor directo, pero tiene 0 o más sucesores directos.

​ ②Los n-1 nodos restantes se pueden dividir en m (m>=0) conjuntos finitos disjuntos T1, T2, T3,...Tm, donde Ti es de nuevo un árbol, llamado subárbol de la raíz. El nodo raíz de cada subárbol tiene exactamente un predecesor inmediato, pero cero o más sucesores inmediatos.

(los árboles se definen recursivamente)

La siguiente figura muestra la estructura lógica de un árbol, similar a un árbol invertido:

 Nota: Un árbol sin un nodo también es un árbol, llamado árbol vacío, y un árbol con un solo nodo también es un árbol.

Prueba uno:

¿El siguiente árbol es o no es árbol? 

Respuesta: No es un árbol, y esta condición no se cumple: el nodo raíz de cada subárbol tiene un único antecesor directo, es decir, no puede formar un ciclo.

Por ejemplo, hay dos predecesores directos de G, A y D, por lo que la estructura no es un árbol.

2.2 Conocimientos básicos sobre los árboles

Toma este árbol como ejemplo.

Grado de un nodo : El número de subárboles contenidos en un nodo se denomina grado del nodo; como se muestra en la figura anterior: A es 3..

Nodo hoja o nodo terminal : Un nodo con un grado de 0 se denomina nodo hoja, como se muestra arriba: K, L, F, G, M, I, J. Los nodos son todos los nodos hoja.
Nodo principal o nodo principal : si un nodo contiene un nodo secundario, este nodo se denomina nodo principal de su nodo secundario; como se muestra en la figura anterior: A es el nodo principal de B y C es el nodo principal de G.

Nodo secundario o child node : El nodo raíz del subárbol contenido en un nodo se denomina nodo secundario del nodo; como se muestra arriba: B es el nodo secundario de A, y G es el nodo secundario de C.

Nodos hermanos : los nodos con el mismo nodo padre se denominan nodos hermanos; como se muestra en la figura anterior: B y C son nodos hermanos , y los primos como E y G no se consideran nodos hermanos.

El grado del árbol : en un árbol, el grado del nodo más grande se llama grado del árbol; como se muestra arriba: el grado del árbol es 3.

La jerarquía de los nodos : a partir de la raíz, la raíz es la primera capa, los nodos secundarios de la raíz son la segunda capa, y así sucesivamente.
La altura o profundidad del árbol : el nivel máximo de nodos en el árbol; como arriba: la altura del árbol es 4.
Antepasados ​​de un nodo : Todos los nodos en la rama desde la raíz hasta el nodo; como se muestra arriba: A es el antepasado de todos los nodos.

3. Árbol binario

3.1 El concepto de árbol binario

Concepto: Un árbol binario es un conjunto finito de nodos, que está vacío o consta de un nodo raíz más dos árboles binarios llamados subárboles izquierdo y derecho.

Características:

1. Cada nodo tiene como máximo dos subárboles, es decir, no hay nodos con grado mayor a 2 en un árbol binario.
2. Los subárboles de un árbol binario se dividen en izquierdo y derecho, y el orden de los subárboles no se puede invertir.

El siguiente es un árbol binario ordinario

3.2 Árbol binario especial

3.2.1 Árbol binario completo

Concepto: Un árbol binario completo es un árbol binario, si el número de nodos en cada capa alcanza el valor máximo, el árbol binario es un
árbol binario completo. Es decir, si un árbol binario tiene K niveles y el número total de nodos es (2^k) -1, entonces es un árbol binario completo.

 3.2.2 Árbol binario completo

 3.3 Propiedades de los árboles binarios

Propiedades de los árboles binarios
1. Si el número de niveles del nodo raíz se especifica como 1, entonces hay como máximo 2^(i-1) nodos en el i-ésimo nivel de un árbol binario no vacío.
2. Si el nivel del nodo raíz se especifica como 1, el número máximo de nodos de un árbol binario con una profundidad de h es 2^h-1.
3. Para cualquier árbol binario, si el número de nodos de hoja de grado 0 es n0 y el número de nodos de rama de grado 2 es n2, entonces n0=n2+1.
4. Si el nivel del nodo raíz se especifica como 1, la profundidad de un árbol binario completo con n nodos , h=Log2(N+1).

3.4 Ejercicios sobre preguntas de opción múltiple relacionadas con las propiedades de los árboles binarios

1. Un árbol binario tiene un total de 399 nodos, de los cuales hay 199 nodos con grado 2, entonces el número de nodos hoja en el árbol binario es ( )
A No existe tal árbol binario
B 200
C 198
D 199

2. En un árbol binario completo con 2n nodos, el número de nodos hoja es ( )
A n
B n+1
C n-1
D n/2

Analizar gramaticalmente:

1: elija B. De acuerdo con la propiedad anterior 3, n0 = n2 + 1 = 200. Es decir, el número de nodos de hoja es 200 (los nodos de hoja son nodos con grado 0)

2: Elija A. El árbol binario solo tiene nodos de 0, 1 y 2 grados, por lo que n2+n1+n0=2*n

Y como n0=n2+1, entonces 2*n0+n1-1=2*n

Debido a que el árbol es un árbol binario completo, n1 solo puede ser 0 o 1.

Cuando n1 es 0, n0 es un decimal, en este caso omitido,

Entonces n1 es igual a 1, entonces n0 es igual a n.

3.5 Implementación de la estructura de cadena de árbol binario

3.5.1 Recorrido de la estructura de cadena de árbol binario

El llamado recorrido (traversal) se refiere a seguir una determinada ruta de búsqueda, y visitar secuencialmente cada nodo del árbol una vez y solo una vez. Las operaciones realizadas por el nodo de acceso
dependen del problema específico de la aplicación. El recorrido es una de las operaciones más importantes en un árbol binario y es
la base para otras operaciones en un árbol binario.

El recorrido

1. NLR: Preorder Traversal (también conocido como preorder traversal): la operación de acceder al nodo raíz ocurre antes de atravesar sus subárboles izquierdo y derecho.
2. LNR: Inorder Traversal - La operación de acceder al nodo raíz ocurre en medio de atravesar sus subárboles izquierdo y derecho.
3. LRN: Postorder Traversal - La operación de acceder al nodo raíz ocurre después de atravesar sus subárboles izquierdo y derecho.
Dado que el nodo visitado debe ser la raíz de un subárbol, N (Nodo), L (Subárbol izquierdo) y R (Subárbol derecho) pueden interpretarse como la raíz, el subárbol izquierdo de la raíz y el subárbol derecho de la raíz. NLR, LNR y LRN también se conocen como recorrido previo a la raíz, recorrido intermedio de la raíz y recorrido posterior a la raíz, respectivamente.

4. Recorrido por orden de nivel: Recorrido por orden de nivel: además del recorrido por orden previo, el recorrido en orden y el recorrido por orden posterior, también puede realizar un recorrido por orden de nivel en árboles binarios. Suponga que el número de capas del nodo raíz del árbol binario es 1, y que el recorrido de orden de nivel debe comenzar desde el nodo raíz del árbol binario, primero visite el nodo raíz de la primera capa, luego visite los nodos en la segunda capa de izquierda a derecha, y luego la tercera El nodo de la capa, y así sucesivamente, el proceso de visitar los nodos del árbol capa por capa de arriba a abajo y de izquierda a derecha es el recorrido del orden de las capas.
 

Gráfico transversal de orden de capa:

 

Ejercicio: Por favor escriba el siguiente recorrido de preorden/inorden/postorden/nivel de orden

 Recorrido de pedido anticipado:

A->B->D->NULO->NULO->E->H->NULO->NULO->I->NULO->NULO->C->F->NULO->NULO->G

->NULO->NULO

Recorrido en orden:

NULO->D->NULO->B->NULO->H->NULO->E->NULO->I->NULO->A->NULO->F->NULO->C->NULO

->G->NULO

Recorrido posterior:

NULO->NULO->D->NULO->NULO->H->NULO->NULO->I->E->B-NULO->NULO->F->NULO->NULO

->G->C->A

层序遍历:A->B->C->D->E->F->G->NULL->NULL->H->I->NULL->NULL->NULL->NULL

3.5.2 Entrenamiento de opción múltiple

1. La secuencia de un árbol binario completo de salida por capas (de izquierda a derecha en la misma capa) es ABCDEFGH. La secuencia de preorden de este árbol binario completo es (
)
A ABDHECFG
B ABCDEFGH
C HDBEAFCG
D HDEBFGCA

2. El recorrido en orden previo y el recorrido en orden del árbol binario son los siguientes: recorrido en orden previo: EFHIGJK; recorrido en orden: HFIEJKG. Entonces, el nodo raíz del árbol binario es
()
AE
BF
CG
DH

3. Suponga que la secuencia de recorrido en orden del árbol binario en la Lección 1: badce, y la secuencia de recorrido posterior al orden: bdeca, entonces la secuencia de recorrido previo al orden del árbol binario es ____.
A adbce
B decab
C debac
D abcde

1.A

Análisis: la estructura del árbol binario se puede dibujar a través del recorrido de orden de niveles, y la secuencia de preorden se puede obtener de acuerdo con la estructura del árbol binario.
2.A

Análisis: Según el recorrido de preorden, E es la raíz.
3.D

Análisis: Según el recorrido posterior al orden, la raíz del árbol binario es a, y el recorrido posterior obtiene que b es el subárbol izquierdo y dce es el subárbol derecho. Se puede dibujar la estructura del árbol binario y luego se puede obtener la secuencia transversal de orden previo.


4. Recursividad

4.1 El concepto de recursividad

Concepto de recursividad: recursividad, es decir, una función se llama a sí misma durante el proceso en ejecución.

Las condiciones requeridas para formar la recursividad:
1. El subproblema debe ser el mismo que el problema original, y es más simple
2. No puede llamarse a sí mismo indefinidamente, y debe haber una salida, que se puede simplificar a no recursiva Procesando.

4.2 El significado central de la recursividad

Divida un problema en varios subproblemas idénticos, entregue el problema grande a los subproblemas y entregue los subproblemas a los subsubproblemas para que lo hagan... El último que está dispuesto para completar el tarea es la salida recursiva.

Tome los números de Fibonacci, por ejemplo:

Preguntamos por el valor del n-ésimo número en la sucesión de Fibonacci

Simplifica para encontrar el valor de n-1 y n-2

Entonces el valor de n-1 y n-2 se simplifica al valor de n-2 y n-3 y n-3 y n-4

..........

Esto es para reducir n a varios subproblemas idénticos, los subproblemas son: todos requieren el valor de los dos primeros números.

Recursivamente hasta n==1, luego devuelve 1 o recurse hasta n==0, devuelve 1. Esta es la salida de la recursividad, y también es la declaración que finalmente se arregla para completar la tarea.

4.3 ¿Cómo escribir una recursividad?

      Tres pasos:

  1. Reducir el problema en varios subproblemas idénticos.
  2. Escribir una salida recursiva
  3. llamar a la función en sí,

La siguiente es una forma recursiva de implementar la secuencia de Fibonacci

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int fabonacci(int n)
{
	if (n < 3)//递归出口
	{
		return 1;
	}
	return fabonacci(n - 1) + fabonacci(n - 2);//根据函数功能实现函数
}
int main()
{
	//1 1 2 3 5 8 13
	int n = 7;
	printf("%d\n", fabonacci(n));
	return 0;
}

Práctica de preguntas comunes de OJ de cinco árboles binarios

5.1 Recorrido de pedido anticipado del árbol binario (Likou )

Darle el nodo raíz del árbol binario  root , devolver el  recorrido de preorden de su valor de nodo 

Entrada: raíz = [1, nulo, 2,3]
 Salida: [1,2,3]

Interfaz a implementar:

int* preorderTraversal(struct TreeNode* root, int* returnSize)
{

}

Idea: solicite un espacio en el área del montón para almacenar el valor del nodo, y luego use la idea recursiva para colocar el nodo 1 en el espacio del montón primero, luego coloque su subárbol izquierdo en el espacio y luego colóquelo en su subárbol derecho.

Escritura recursiva:

Escriba la salida recursiva primero:

if(root==NULL)
{
    return;
}

poner en el nodo raíz

ret[*returnSize]=root->val;
*returnSize=(*returnSize)+1;

Finalmente, necesitamos atravesar el subárbol izquierdo y el subárbol derecho restantes.Necesitamos una función para resolver el problema de recorrido restante, y la función para resolver este problema es la función que escribimos, es decir, se puede llamar a la función misma.
Otra pregunta es cuánto espacio deberíamos abrir en el área del montón, aquí uso la recursividad para encontrar la cantidad de nodos en el árbol binario

Escribir recursividad en tres pasos

1. Convierta el problema en varios problemas pequeños, y cada árbol debe satisfacer: la cantidad de nodos en el árbol == 1 + la cantidad de nodos en el subárbol izquierdo + la cantidad de nodos en el subárbol derecho.

2. Escribir salida recursiva: si el árbol está vacío, devuelve 0.

3. Llame a la función misma.

 int size(struct TreeNode* root)
 {
     return root==NULL?0:1+size(root->left)+size(root->right);
 }
 void traversal(struct TreeNode* root,int* returnSize,int* ret)
 {
    if(root==NULL)
    {
        return;
    }
    ret[*returnSize]=root->val;
    *returnSize=(*returnSize)+1;
    traversal(root->left,returnSize,ret);
    traversal(root->right,returnSize,ret);
 }
 int size(struct TreeNode* root)
 {
     return root==NULL?0:1+size(root->left)+size(root->right);
 }
int* preorderTraversal(struct TreeNode* root, int* returnSize)
{
    int s=size(root);
    *returnSize=0;
    int* ret=malloc(sizeof(int)*s);
    traversal(root,returnSize,ret);
    return ret;
}

5.2 La profundidad máxima del árbol binario (fuerza de hebilla)

Dado un árbol binario, encuentre su profundidad máxima.

La profundidad de un árbol binario es el número de nodos en el camino más largo desde el nodo raíz hasta el nodo hoja más lejano.

Explicación: un nodo hoja es un nodo que no tiene nodos secundarios.

Ejemplo:
Dado un árbol binario [3,9,20,null,null,15,7],

  3 
   / \ 
  9 20 
    / \ 
   15 7 
devuelve su profundidad máxima de 3 .

Idea: recursividad directa

Tres pasos:

1. Convierta el problema en varios problemas pequeños idénticos, cada árbol debe satisfacer: profundidad máxima == 1+ (la altura del subárbol izquierdo>la altura del subárbol derecho? La altura del subárbol izquierdo: la altura del subárbol derecho subárbol).

2. Salida recursiva, cuando la dirección del nodo está vacía, devuelve 0.

3. Llame a la función misma.

int maxDepth(struct TreeNode* root)
{
    if(root==NULL)
    {
        return 0;
    }
    return 1+fmax(maxDepth(root->left),maxDepth(root->right));
}

 5.3 Árbol binario equilibrado (fuerza de hebilla)

Dado un árbol binario, determine si es un árbol binario altamente balanceado.

En este problema, un árbol binario de altura equilibrada se define como:

El valor absoluto de la diferencia de altura entre los subárboles izquierdo y derecho de cada nodo  de un árbol binario no excede de 1.

 

Entrada: raíz = [3,9,20, nulo, nulo, 15,7]
 Salida: verdadero

Idea: recursividad directa

Tres pasos:

1. Convierta el problema en varios problemas pequeños idénticos, y cada árbol debe satisfacer: el nodo raíz satisface las condiciones de un árbol equilibrado && el subárbol izquierdo es un árbol equilibrado && el subárbol derecho es un árbol equilibrado.

2. Salida recursiva, cuando la dirección del nodo está vacía, devuelve verdadero.

3. Llame a la función misma.

int height(struct TreeNode* root)
{
    if(root==NULL)
    {
        return 0;
    }
    return 1+fmax(height(root->left),height(root->right));
}
bool isBalanced(struct TreeNode* root)
{
    if(root==NULL)
    {
        return true;
    }
    return abs(height(root->left)-height(root->right))<=1 && 
    isBalanced(root->left) && 
    isBalanced(root->right);
}

Gracias por mirar, le invitamos a que le guste, comente y recopile. Si tiene alguna pregunta, no dude en comunicarse con el autor.

Supongo que te gusta

Origin blog.csdn.net/m0_62171658/article/details/123433827
Recomendado
Clasificación