Algunos de los usos más comunes que tienen estos arboles son los de: árboles binarios de búsqueda, montículos binarios, y codificación de Huffman.
Imagen que demuestra la apariencia de un árbol binario.
Estructura de un árbol binario
Cada nodo tiene un dato, para el ordenamiento necesita una función de procedencia (de origen) y una regla de orden (esta regla implementa el orden relativo de los datos padre e hijos), el grado de un nodo es la cantidad de hijos que tiene (máximo dos).
Estructura típica de un nodo.
La profundidad de un nodo es el camino de la raíz al nodo, la profundidad de un árbol es la profundidad de la hoja más profunda.
Análisis asintótico
Un árbol balanceado con n = 8 y profundidad tres
El peor caso de falta de balance para n = 8 tiene profundidad seis
Asintóticamente lineal.
Rotaciones
Ayudan a entender un problema cuando un nodo es capaz de detectar in imbalance (esto sucede cuando se agrega o elimina un nodo del árbol), estas rotaciones proceden recursivamente hasta la raíz hasta que no haya imbalance.
Existen cuatro distintos tipos de rotación, como:
Imagen que demuestra la rotación simple izquierda.
Imagen que demuestra la rotación simple derecha.
Imagen que demuestra la rotación doble izquierda-derecha.
Estas son las condiciones que se tienen que llevar a cabo para poder realizar la operación de rotaciones.
Inserción
Proceso de inserción, número 5.
Ejemplo de pseudocódigo de inserción
PROC InsertarABB(árbol:TABB; dato:TElemento)
VARIABLES
nuevonodo,pav,pret:TABB
clavenueva:Tclave
ele:TElemento
INICIO
nuevonodo <- NUEVO(TNodoABB)
nuevonodo^.izq <- NULO
nuevonodo^.der <- NULO
nuevonodo^.elem <- dato
SI ABBVacío (árbol) ENTONCES
árbol <- nuevonodo
ENOTROCASO
clavenueva <- dato.clave
pav <- árbol // Puntero Avanzado
pret <- NULO // Puntero Retrasado
MIENTRAS (pav <- NULO) HACER
pret <- pav
ele = pav^.elem
SI (clavenueva < ele.clave ) ENTONCES
pav <- pav^.izq
EN OTRO CASO
pav <- pav^.dch
FINSI
FINMIENTRAS
ele = pret^.elem
SI (clavenueva < ele.clave ) ENTONCES
pret^.izq <- nuevonodo
EN OTRO CASO
pret^.dch <- nuevonodo
FINSI
FINSI
FIN
Eliminación
Borrar un nodo sin hijos o nodo hoja: simplemente se borra y se establece a NULL el apuntador de su padre.
Aquí se borra el nodo "74".
Borrar un nodo con un sub-árbol hijo: se borra el nodo y se asigna su sub-árbol hijo como sub-árbol de su padre.
Aquí se elimina el nodo "70".
Borrar un nodo con dos sub-árboles hijo: la solución está en reemplazar el valor del nodo por el de su padre o por el de su hijo en inorden y posteriormente borrar este nodo. Su padre en inorden será el nodo más a la derecha de su sub-árbol izquierdo (mayor nodo del sub-arbol izquierdo), y su hijo el nodo más a la izquierda de su sub-árbol derecho (menor nodo del subarbol derecho).
Aquí se elimina el nodo "59".
Ejemplo de codificación de eliminación
void borrar(tArbol **a, int elem)
{
void reemplazar(tArbol **a, tArbol **aux);
tArbol *aux;
if (*a == NULL)
return;
if ((*a)->clave < elem)
borrar(&(*a)->hDerecho, elem);
else if ((*a)->clave > elem)
borrar(&(*a)->hIzquierdo, elem);
else if ((*a)->clave == elem)
{
aux = *a;
if ((*a)->hIzquierdo == NULL)
*a = (*a)->hDerecho;
else if ((*a)->hDerecho == NULL)
*a = (*a)->hIzquierdo;
else
reemplazar(&(*a)->hIzquierdo, &aux);
free(aux);
}
}
void reemplazar(tArbol **a, tArbol **aux)
{
if ((*a)->hDerecho == NULL)
{
(*aux)->clave = (*a)->clave;
*aux = *a;
*a = (*a)->hIzquierdo;
}
else
reemplazar(&(*a)->hDerecho, aux);
}
Referencias:
A una de las gráficas le falta el fondo blanco. 10.
ResponderEliminar