Download árbol árbol no -red

Document related concepts

Árbol binario wikipedia , lookup

Árbol AVL wikipedia , lookup

Rotación de árboles wikipedia , lookup

Árbol binario de búsqueda wikipedia , lookup

Recorrido de árboles wikipedia , lookup

Transcript
3.1 Definición de árboles
Un árbol es una estructura no lineal en la que cada nodo puede apuntar a uno o varios
nodos.
En relación con nodos se pueden definir conceptos como:


Nodo hijo: cualquiera de los nodos apuntados por uno de los nodos del
árbol. En el ejemplo, 'L' y 'M' son hijos de 'G'.
Nodo padre: nodo que contiene un puntero al nodo actual. En el ejemplo,
el nodo 'A' es padre de 'B', 'C' y 'D'.
En cuanto a la posición dentro del árbol, encontramos:



Nodo raíz: nodo que no tiene padre. Este es el nodo que usaremos para
referirnos al árbol. En el ejemplo, ese nodo es el 'A'.
Nodo hoja: nodo que no tiene hijos. En el ejemplo hay varios: 'F', 'H', 'I',
'K', 'L', 'M', 'N' y 'O'.
Nodo rama: aunque esta definición apenas la usaremos, estos son los
nodos que no pertenecen a ninguna de las dos categorías anteriores. En el
ejemplo: 'B', 'C', 'D', 'E', 'G' y 'J'.
.
Existen otros conceptos que definen las características del árbol, en relación a su
tamaño:




Orden: es el número potencial de hijos que puede tener cada elemento de
árbol. De este modo, diremos que un árbol en el que cada nodo puede
apuntar a otros dos es de orden dos, si puede apuntar a tres será de orden
tres, etc. (árbol)
Grado: el número de hijos que tiene el elemento con más hijos dentro del
árbol. En el árbol del ejemplo, el grado es tres, ya que tanto 'A' como 'D'
tienen tres hijos, y no existen elementos con más de tres hijos.(nodo)
Nivel: se define para cada elemento del árbol como la distancia a la raíz,
medida en nodos. El nivel de la raíz es cero y el de sus hijos uno. Así
sucesivamente. En el ejemplo, el nodo 'D' tiene nivel 1, el nodo 'G' tiene
nivel 2, y el nodo 'N', nivel 3. (árbol)
Altura: la altura de un árbol se define como el nivel del nodo de mayor
nivel. Como cada nodo de un árbol puede considerarse a su vez como la
raíz de un árbol, también podemos hablar de altura de ramas. El árbol del
ejemplo tiene altura 3, la rama 'B' tiene altura 2, la rama 'G' tiene altura 1,
la 'H' cero, etc. (nodo)
Árboles binarios.
Un árbol binario esta vacío o consta de un nodo denominado raíz junto con dos
árboles binarios llamados subárbol izquierdo y subárbol derecho de la raíz.
Además de que los árboles binarios se emplean para búsquedas, la recuperación
de información es una de las aplicaciones más importantes, y para ello existen los
árboles de búsqueda binaria.
La única manera de construir un árbol binario con un nodo consiste en hacer que
el nodo sea su raíz y que estén vacíos sus subárboles izquierdo y derecho (representan
un apuntador a NULL), esto significa que se trata de un árbol ordinario.
Con dos nodos en el árbol, uno de ellos será la raíz y el otro estará en un
subárbol. Así, uno de los subárboles de la izquierda o derecha debe estar vacío y el otro
contendrá un nodo. De ahí que haya dos árboles binarios diferentes con dos nodos.
Definición recursiva de árbol. Un árbol es una estructura compuesta por un dato
y un conjunto de árboles.
Ejemplos:
Un sistema de ficheros.
La estructura de un documento(capítulos, apartados, subapartados, …)
Un árbol genealógico.
Definición de árbol no recursiva. Un árbol consiste en un conjunto de nodos y
un conjunto de aristas.
Se detecta el nodo o raíz.
Para cada nodo hay un camino (secuencia de aristas) único desde la raíz.
Ejemplo:
A cada nodo h, excepto la raíz, le llega una arista de otro nodo p.
p= padre.
h= hijo.
Recorrido de árboles.
Una de las cosas que podemos hacer con un árbol es movernos a través de la
información que este contiene. La manera de moverse a través de las ramas de un
árbol es siguiendo las referencias de los nodos que las componen. Los recorridos
dependen en gran medida del tipo y propósito del árbol.
Cuando escuchamos hablar de un recorrido de árbol la primera pregunta que nos
hacemos es ¿De que manera es que se hace un recorrido? Pues la manera más
común de recorrer un árbol es de forma recurrente.
Hay tres formas de recorrer un árbol completo, y las tres se suelen implementar
mediante recursividad. En los tres casos se recorre cada nodo y todas las ramas una
por una.
Recorrido Pre-Orden (N-I-D): En este recorrido lo primero que se obtiene o
evalúa es el nodo, antes de recorrer las ramas; posteriormente se recorren las ramas
izquierdas y finalmente las ramas de la derecha.
El orden es: Nodo – Izquierda – Derecha (N – I – D).
Ejemplo:
Recorrido In- Orden (I- N-D): En este recorrido se procesa la primera rama
(rama izquierda), después el nodo y finalmente la ultima rama (rama derecha). El
orden es: Izquierda – Nodo – Derecha (I – N – D).
Ejemplo:
Recorrido Post- Orden (I-D-R): En este recorrido primero se
procesan las ramas para finalmente procesar el nodo. El orden de este
recorrido es: Izquierda – Derecha – Nodo (I – D – N).
Ejemplo:
Ejemplo general de los recorridos:
Recorridos
in-orden : 10 , 30 , 50 ,
55 , 60 , 80
pre-orden : 60 , 30 , 10 ,
50 , 55 , 80
post-orden : 10 , 55 , 50
, 30 , 80 , 60
ÁRBOLES BINARIOS DE BUSQUEDA (ABB)
8
10
3
1
6
4
9
7
14
18
En este tipo de árboles cada nodo tiene asociado un valor de clave y este valor de clave
es mayor o igual que los valores de clave de los nodos de su subárbol izquierdo y menor
o igual que todos los de su subárbol derecho. Según el tipo de aplicación puede no
permitirse valores iguales en uno o ambos subárboles. Si se realiza un recorrido en
Inorden por el árbol accederemos a los valores de clave en orden ascendente.
La búsqueda en árboles binarios es un método de búsqueda simple, dinámico y eficiente
considerado como uno de los fundamentales en Ciencia de la Computación.
Si un ABB no esta ordenado se le dará se le llamara “DEGENERADO”.
MOTIVACION:
Los AB no ordenados son de poco interés. La falta de ordenación en un AB hace
injustificable una estructura enlazada de árbol prefiriéndose una lista.
CARACTERISTICAS:
Cada nodo tiene dos hijos
El subárbol izquierdo es el árbol vació o es un subárbol que contiene nodos
cuyas claves es menor que la suya.
El subárbol derecho es el árbol vació o es un subárbol que contiene nodos
cuyas claves es mayor que la suya.
UTILIDAD:
Almacenar estructuras lineales (que normalmente serian listas) mejorando la
complejidad de las búsquedas.
El árbol AVL toma su nombre de las iniciales de los apellidos de sus inventores,
Adelson-Velskii y Landis. Lo dieron a conocer en la publicación de un artículo en
1962: "An algorithm for the organization of information" ("Un algoritmo para la
organización de la información").
Los árboles binarios de búsqueda tal y como los hemos visto, adolecen del
problema de
que en el peor de los casos pueden tender parcialmente hacia el árbol degenerado, de
manera que
la búsqueda de un elemento cualquiera puede ser de un orden superior a O(lg n), y
tender a O(n).
Este problema queda solucionado con los árboles AVL, o balanceados en altura.
Los árboles AVL están siempre equilibrados de tal modo que para todos los
nodos, la altura de la rama izquierda no difiere en más de una unidad de la altura
de la rama derecha.
Gracias a esta forma de equilibrio (o balanceo), la complejidad de una búsqueda
en uno de estos árboles se mantiene siempre en orden de complejidad O (log n).
El factor de equilibrio puede ser almacenado directamente en cada nodo o ser
computado a partir de las alturas de los subárboles.
Para conseguir esta propiedad de equilibrio, la inserción y el borrado de los nodos se
ha de realizar de una forma especial. Si al realizar una operación de inserción o
borrado se rompe la condición de equilibrio, hay que realizar una serie de rotaciones
de los nodos.
Un árbol AVL es un árbol binario de búsqueda en el cual para cada nodo las alturas de
los subárboles difieren a lo sumo en uno.
Montículos (Heaps)
Un montículo es un árbol binario en el que para cada nodo n (excepto para el raíz), su
clave es mayor o igual que la de su padre. Sirve para la implementación de colas con
Prioridad
Factor de equilibrio
Cada nodo, además de la información que se pretende almacenar, debe tener los dos
punteros a los árboles derecho e izquierdo, igual que los árboles binarios de búsqueda
(ABB), y además el dato que controla el factor de equilibrio.
El factor de equilibrio
Es la diferencia entre las alturas del árbol derecho y el izquierdo:
Árbol binario equilibrado
Árbol binario no equilibrado
Operaciones
Las operaciones básicas de un árbol AVL implican generalmente el realizar los
mismos algoritmos que serían realizados en un árbol binario de búsqueda
desequilibrado, pero precedido o seguido por una o más de las llamadas "rotaciones
AVL".
Inserción
La inserción en un árbol de AVL puede ser realizada insertando el valor dado en el
árbol como si fuera un árbol de búsqueda binario desequilibrado y después
retrocediendo hacia la raíz, rotando sobre cualquier nodo que pueda haberse
desequilibrado durante la inserción.
Extracción
El problema de la extracción puede resolverse en O (log n) pasos. Una extracción trae
consigo una disminución de la altura de la rama donde se extrajo y tendrá como efecto
un cambio en el factor de equilibrio del nodo padre de la rama en cuestión, pudiendo
necesitarse una rotación.
Esta disminución de la altura y la corrección de los factores de equilibrio con sus
posibles rotaciones asociadas pueden propagarse hasta la raíz.
Búsqueda
Las búsquedas se realizan de la misma manera que en los ABB, pero al estar el árbol
equilibrado la complejidad de la búsqueda nunca excederá de O (log n).
ÁRBOLES DE BUSQUEDA BINARIA
Definición de Árboles de Búsqueda Binaria
Se trata de árboles de orden 2 en los que se cumple que para cada nodo, el valor de la
clave de la raíz del subárbol izquierdo es menor que el valor de la clave del nodo y que
el valor de la clave raíz del subárbol derecho es mayor que el valor de la clave del nodo.
Propiedades de los ABB
 El árbol vació es un ABB
 Los árboles izquierdo y derecho son ABBs.
 La llave k es mayor que todas las llaves almacenadas en el ABB izquierdo.
 La llave k es menor que todas las llaves almacenadas en el ABB derecho
Operaciones de los ABB







Buscar un elemento
Insertar un elemento
Borrar un elemento
Movimientos a través del árbol:
Izquierda
Derecha
Raíz
Búsqueda de un elemento.
El proceso de búsqueda en un Árbol Binario de Búsqueda se puede realizar
recursivamente o iterativamente. Primero se comprueba la raíz. Si el valor de clave es
igual al elemento a buscar, determinamos que el valor existe. Si el elemento es menor
realizamos una búsqueda recursiva en el subárbol izquierdo, si por el contrario es mayor
realizamos la búsqueda en el subárbol derecho. Si alcanzamos un nodo hoja y no está el
elemento, determinamos que éste no se encuentra en el árbol.
// Para buscar un valor x en el árbol
// Será semi-recursivo
public Nodo buscar (double x) {
return buscar(x, this.raiz);
}
private Nodo buscar (double x, Nodo p) {
// Casos base
if (p == null) return null;
// No está
if (p.info == x) return p;
// Lo encontramos
// Paso recursivo
if (p.info > x)
return buscar(x, p.izq);
else
return buscar(x, p.der);
}
}
Insertar un elemento.
El insertar un elemento es similar a la búsqueda. Si el árbol pasado por parámetro está
vacío se crea un nuevo nodo para él y se lee su valor de clave correspondiente. Si no lo
está, se comprueba si el elemento a insertar es menor con lo que insertamos el elemento
en el subárbol izquierdo, o mayor, insertando el elemento en el subárbol derecho.
public class ABB {
public Nodo raiz;
// Inicializa el árbol de búsqueda binaria.
public ABB() {
this.raiz = null;
}
// Para insertar el valor x.
public void insertar (double x) {
// Creación del nuevo nodo
Nodo p = new Nodo(x);
// Se busca donde va el nuevo nodo
Nodo q = this.raiz;
Nodo f = null;
while (q != null) {
f = q;
if (q.info > p.info)
q = q.izq;
else
q = q.der;
}
// Inserción del nuevo nodo
if (f == null)
this.raiz = p;
else {
if (f.info > p.info)
f.izq = p;
else
f.der = p;
}
}
Eliminar de un elemento.
Para borrar un elemento también nos debemos vasar en mismo procedimiento de
búsqueda.




si se trata de un nodo hoja se tiene que borrar directamente.
Si se trata de un nodo rama, no lo podemos eliminar, puesto que
podríamos eliminar todos los elementos del árbol.
En su lugar buscaremos el nodo mas a la izquierda del subárbol derecho,
o el mas a la derecha del subárbol izquierdo e intercambiamos sus
valores.
Y ahora si se podrá eliminar en nodo hoja.
Comprobación de un árbol vació
Para comprobar si un árbol esta vacío es cuando su raíz es NULL.
Comprobación si el nodo es hoja.
Basca con comprobar si el árbol izq. Como el der. Están vacíos. Si ambos lo esta es
nodo de hoja.
/* -----------------------------------------------------------------------------------------AQUÍ IRIA LA SECCION OPERACIONES SOBRE ARBOLES ABB
CALCULAR NUMERO DE NODOS
COMPROBAR SI EL NODO ES HOJA
CALCULAR EL NIVEL DE UN NODO
CALCULAR LA ALTURA DEL ARBOL
NO ME LA ENVIO EL EQUIPO CORRESPONDIENTE, ASI QUE LA TENDRAN
QUE INVESTIGAR
---------------------------------------------------------------------------------------- */
Árboles AVL
Un árbol AVL (llamado así por las iniciales de sus inventores: AdelsonVelskii y Blandís) es un árbol binario de búsqueda en el que para cada nodo,
las alturas de sus subárboles izquierdo y derecho no difieren en más de 1.
No se trata de árboles perfectamente equilibrados, pero sí son lo
suficientemente equilibrados como para que su comportamiento sea lo
bastante bueno como para usarlos donde los ABB no garantizan tiempos de
búsqueda óptimos.
El algoritmo para mantener un árbol AVL equilibrado se basa en
reequilibrados locales, de modo que no es necesario explorar todo el árbol
después de cada inserción o borrado.
Arboles equilibrados
 Para resolver este inconveniente podemos recurrir a los árboles AVL.
 El problema de estos algoritmos es que requieren explorar y reconstruir
todo el árbol cada vez que se inserta o se elimina un elemento, de modo
que lo que ganamos al acortar las búsquedas, teniendo que hacer menos
comparaciones, lo perdemos equilibrando el árbol.
OPERACIONES AVL
Los AVL son también ABB, de modo que mantienen todas las operaciones
que poseen éstos. Las nuevas operaciones son las de equilibrar el árbol,
pero eso se hace como parte de las operaciones de insertado y borrado.
 Cada nodo, además de la información que se pretende almacenar, debe
tener los dos punteros a los árboles derecho e izquierdo, igual que los
ABB, y además un miembro nuevo: el factor de equilibrio.
 El factor de equilibrio es la diferencia entre las alturas del árbol derecho
y el izquierdo:
 FE = altura subárbol derecho - altura subárbol izquierdo; Por
definición, para un árbol AVL, este valor debe ser -1, 0 ó 1.
Rotaciones Simples en árboles AVL
Esta Rotación se usara Cuando un subárbol derecho o izquierdo sea 2
unidades mas alto que el del otro es decir que su FE sea de 2.
Padre
P
5
3
A
n
Q
Q
10
9
B
n
10
P
5
12
C
n+1
3
A
n
9
B
n
Rotación doble a la derecha (DD):
Esta rotación se usará cuando el subárbol izquierdo de un nodo sea 2 unidades más alto
que el derecho, es decir, cuando su FE sea de -2. Y además, la raíz del subárbol
izquierdo tenga una FE de 1, es decir, que esté cargado a la derecha.
Este es uno de los posibles árboles que pueden presentar esta estructura, pero hay otras
dos posibilidades. El nodo R puede tener una FE de -1, 0 ó 1. En cada uno de esos casos
los árboles izquierdo y derecho de R (B y C) pueden tener alturas de n y n-1, n y n, o n1 y n, respectivamente.
El modo de realizar la rotación es independiente de la estructura del árbol R, cualquiera
de las tres produce resultados equivalentes. Haremos el análisis para el caso en que FE
sea -1.
En este caso tendremos que realizar dos rotaciones.
Llamaremos P al nodo que muestra el desequilibrio, el que tiene una FE de -2.
Llamaremos Q al nodo raíz del subárbol izquierdo de P, y R al nodo raíz del subárbol
derecho de Q.
1. Haremos una rotación simple de Q a la izquierda.
2. Después, haremos una rotación simple de P a la
derecha.
Con más detalle, procederemos del siguiente modo:
1. Pasamos el subárbol izquierdo del nodo R como
subárbol derecho de Q. Esto mantiene el árbol como
ABB, ya que todos los valores a la izquierda de R
siguen estando a la derecha de Q.
2. Ahora, el nodo R pasa a tomar la posición del nodo
Q, es decir, hacemos que la raíz del subárbol
izquierdo de P sea el nodo R en lugar de Q.
3. El árbol Q pasa a ser el subárbol izquierdo del nodo
R.
4. Pasamos el subárbol derecho del nodo R como
subárbol izquierdo de P. Esto mantiene el árbol como
ABB, ya que todos los valores a la derecha de R
siguen estando a la izquierda de P.
5. Ahora, el nodo R pasa a tomar la posición del nodo
P, es decir, hacemos que la entrada al árbol sea el
nodo R, en lugar del nodo P. Como en los casos
anteriores, previamente, P puede que fuese un árbol
completo o un subárbol de otro nodo de menor
altura.
6. El árbol P pasa a ser el subárbol derecho del nodo R.
Rotación doble a la izquierda (DI):
Esta rotación se usará cuando el subárbol derecho de un nodo sea 2 unidades más alto
que el izquierdo, es decir, cuando su FE sea de 2. Y además, la raíz del subárbol
derecho tenga una FE de -1, es decir, que esté cargado a la izquierda. Se trata del caso
simétrico del anterior.
En este caso también tendremos que realizar dos rotaciones.
Llamaremos P al nodo que muestra el desequilibrio, el que tiene una FE de 2.
Llamaremos Q al nodo raíz del subárbol derecho de P, y R al nodo raíz del subárbol
izquierdo de Q.
1. Haremos una rotación simple de Q a la derecha.
2. Después, haremos una rotación simple de P a la
izquierda.
Con más detalle, procederemos del siguiente modo:
1. Pasamos el subárbol derecho del nodo R como
subárbol izquierdo de Q. Esto mantiene el árbol
como ABB, ya que todos los valores a la derecha de
R siguen estando a la izquierda de Q.
2. Ahora, el nodo R pasa a tomar la posición del nodo
Q, es decir, hacemos que la raíz del subárbol derecho
de P sea el nodo R en lugar de Q.
3. El árbol Q pasa a ser el subárbol derecho del nodo R.
4. Pasamos el subárbol izquierdo del nodo R como
subárbol derecho de P. Esto mantiene el árbol como
ABB, ya que todos los valores a la izquierda de R
siguen estando a la derecha de P.
5. Ahora, el nodo R pasa a tomar la posición del nodo
P, es decir, hacemos que la entrada al árbol sea el
nodo R, en lugar del nodo P. Como en los casos
anteriores, previamente, P puede que fuese un árbol
completo o un subárbol de otro nodo de menor
altura.
6. El árbol P pasa a ser el subárbol izquierdo del nodo
R.
/* -----------------------------------------------------------------------------EN ESTA ULTIMA SECCION VA “APLICACIONES DE ARBOLES”, EL CUAL
NO FUE ENVIADO POR EL EQUIPO CORRESPONDIENTE, ASI QUE TAMBIEN
LO TENDRAN QUE INVESTIGAR
------------------------------------------------------------------------------*/