Download Tema 11

Document related concepts

Recorrido de árboles wikipedia , lookup

Árbol binario wikipedia , lookup

Árbol binario de búsqueda wikipedia , lookup

Treap wikipedia , lookup

Rotación de árboles wikipedia , lookup

Transcript
Metodología y Tecnología de la
Programación
Curso 2008/09
Tema 11
Árboles
Temario
Tema 11. Árboles
11.1
11.2
11.3
11.4
11.5
11.6
11.7
Terminología Fundamental
TDA Árbol
TDA Árbol Binario
TDA Árbol basado en su Definición Recursiva
TDA Árbol Binario basado en su Definición Recursiva
Árboles Parcialmente Ordenados: Colas de Prioridad
Árboles Binarios de Búsqueda: Conjuntos
Metodología y Tecnología de la Programación
Tema 11. Árboles
2
11.1 Terminología Fundamental
Árbol:
Colección de elementos.
Existe una estructura jerárquica:
⇒ relación de paternidad entre los elementos.
elementos: nodos ⇒ nodo raíz.
Matemáticamente:
grafo no orientado, conexo y acíclico.
existe un vértice destacado llamado raíz.
Metodología y Tecnología de la Programación
Tema 11. Árboles
3
11.1 Terminología Fundamental
Árbol A n-ario:
O bien es el conjunto vacío ⇒ árbol vacío.
O bien no es vacío:
elemento raíz.
A1,…,Am subárboles.
Definiciones:
Árbol ordenado: el orden de los subárboles importa.
La raíz de A es padre de la raíz de A1,…,Am.
Las raíces de A1,…,Am son hijos de la raíz de A.
Metodología y Tecnología de la Programación
Tema 11. Árboles
4
11.1 Terminología Fundamental
Árbol binario A:
O bien es el conjunto vacío ⇒ árbol vacío.
O bien no es vacío:
elemento raíz.
A1, A2 subárboles izquierdo y derecho.
Definiciones:
No es lo mismo un árbol 2-ario que un árbol binario:
⇒ en el árbol binario se distingue entre súbárboles izquierdo y derecho.
Los términos padre e hijo descritos para árboles n-arios son también utilizados
para árboles binarios.
Metodología y Tecnología de la Programación
Tema 11. Árboles
5
11.1 Terminología Fundamental
Otros términos comunes:
Camino del nodo n1 a nk:
Secuencia de nodos n1,…, nk
tal que ni es padre de ni+1
Longitud de un camino:
Número de nodos del camino menos 1.
Existe un camino de longitud 0 de todo nodo a sí mismo.
Ascendiente/Descendiente:
Un a es ascendiente de b (y b descendiente de a), si existe un camino de a a b.
Todo nodo es ascendiente (y descendiente) de sí mismo.
Los ascendientes (y descendientes) de un nodo, excluido el propio nodo, se
denominan ascendientes (y descendientes) propios.
Hoja:
Nodo sin descendientes propios.
Metodología y Tecnología de la Programación
Tema 11. Árboles
6
11.1 Terminología Fundamental
Altura:
La altura de un nodo es la longitud del camino más largo de
ese nodo a una hoja.
La altura de un árbol es la altura de la raíz.
Profundidad:
La profundidad de un nodo es la longitud del camino único
desde ese nodo a la raíz.
Metodología y Tecnología de la Programación
Tema 11. Árboles
7
11.2 TDA Árbol: Descripción
Formas de construir árboles:
Añadir un nodo a un árbol:
como hijo más a la izquierda.
como hermano derecho.
Utilizar directamente en la definición recursiva de árboles.
Entradas:
A1,…,Am
nodo raiz.
Metodología y Tecnología de la Programación
Tema 11. Árboles
8
11.2 TDA Árbol: Operaciones
Operaciones de construcción:
CREA
Operaciones de posicionamiento:
RAIZ
PADRE
HIJOIZQUIERDO, HERMANODERECHO
Operaciones de consulta:
VACIO
RECUPERA
NULO
Operaciones de modificación:
INSERTARAIZ, INSERTAHIJO, INSERTAHERMANO
SUPRIMEHIJO, SUPRIMEHERMANO
MODIFICA
Metodología y Tecnología de la Programación
Tema 11. Árboles
9
11.2 TDA Árbol: Especificación
Arbol = TDA con operaciones crea, raiz, padre, hijoIzquierdo,
hermanoDerecho, vacio, recupera, nulo, insertaRaiz, insertaHijo,
insertaHermano, suprimeHijo, suprimeHermano, modifica.
DESCRIPCIÓN:
Los valores del TDA Arbol son árboles n-arios donde cada nodo contiene un dato del
tipo Elemento. Los nodos son del tipo Nodo. Los árboles son mutables:
insertaRaiz, insertaHijo, insertaHermano, suprimeHijo,
suprimeHermano y modifica añaden, eliminan y modifican respectivamente
elementos de un árbol.
OPERACIONES:
crea() devuelve (A:Arbol)
efecto: Devuelve el árbol vacío A.
raiz(A:Arbol) devuelve (Nodo)
efecto: Devuelve la raíz de A. Si A es vacío, devuelve nulo.
Metodología y Tecnología de la Programación
Tema 11. Árboles
10
11.2 TDA Árbol: Especificación
padre(A:Arbol; N:Nodo) devuelve (Nodo)
requerimientos: N ≠ nulo.
efecto: Devuelve el padre de N. Si N es la raíz, devuelve nulo.
hijoIzquierdo(A:Arbol; N:Nodo) devuelve (Nodo)
requerimientos: N ≠ nulo.
efecto: Devuelve el hijo más a la izquierda de N. Si N no tiene hijos, devuelve nulo.
hermanoDerecho(A:Arbol; N:Nodo) devuelve (Nodo)
requerimientos: N ≠ nulo.
efecto: Devuelve el hermano derecho de N. Si N no tiene hermano derecho,
devuelve nulo.
vacio(A:Arbol) devuelve (booleano)
efecto: Devuelve cierto si A es vacío, y falso en caso contrario.
recupera(A:Arbol; N:Nodo) devuelve (Elemento)
requerimientos: N ≠ nulo.
efecto: Devuelve el elemento contenido en el nodo N.
Metodología y Tecnología de la Programación
Tema 11. Árboles
11
11.2 TDA Árbol: Especificación
nulo(A:Arbol; N:Nodo) devuelve (booleano)
efecto: Devuelve cierto si N es nulo, y falso en caso contrario.
insertaRaiz(A:Arbol; E:Elemento)
requerimientos: A = vacío.
efecto: Añade un nodo, con contenido E, como raíz de A.
insertaHijo(A:Arbol; N:Nodo; E:Elemento)
requerimientos: N ≠ nulo.
modifica: A.
efecto: Añade un nodo, con contenido E, como hijo más a la izquierda de N.
insertaHermano(A:Arbol; N:Nodo; E:Elemento)
requerimientos: N ≠ nulo. N ≠ raíz.
modifica: A.
efecto: Añade un nodo, con contenido E, como hermano derecho de N.
Metodología y Tecnología de la Programación
Tema 11. Árboles
12
11.2 TDA Árbol: Especificación
suprimeHijo(A:Arbol; N:Nodo)
requerimientos: N ≠ nulo. hijoIzquierdo(N) ≠ nulo.
modifica: A.
efecto: Suprime el hijo más a la izquierda de N y todos sus descendientes.
suprimeHermano(A:Arbol; N:Nodo)
requerimientos: N ≠ nulo. hermanoDerecho(N) ≠ nulo.
modifica: A.
efecto: Suprime el hermano derecho de N y todos sus descendientes.
modifica(A:Arbol; N:Nodo; E:Elemento)
requerimientos: N ≠ nulo.
modifica: A.
efecto: Modifica el contenido de N, cambiándolo por el nuevo contenido E.
Metodología y Tecnología de la Programación
Tema 11. Árboles
13
11.2 TDA Árbol: Métodos en Java
Clase Arbol
class Arbol
Clases Internas
class Arbol.Nodo
Constructores
Arbol()
Métodos
Arbol.Nodo raiz()
Arbol.Nodo padre(Arbol.Nodo n)
Arbol.Nodo hijoIzquierdo(Arbol.Nodo n)
Arbol.Nodo hermanoDerecho(Arbol.Nodo n)
boolean vacio()
Elemento recupera(Arbol.Nodo n)
boolean nulo(Arbol.Nodo n)
void insertaRaiz(Elemento e)
void insertaHijo(Arbol.Nodo n, Elemento e)
void insertaHermano(Arbol.Nodo n, Elemento e)
void suprimeHijo(Arbol.Nodo n)
void suprimeHermano(Arbol.Nodo n)
void modifica(Arbol.Nodo n, Elemento e)
Metodología y Tecnología de la Programación
Tema 11. Árboles
14
11.2 TDA Árbol: Esquemas de recorrido
Esquemas de recorrido en árboles fundamentales:
Preorden(A):
Si A es vacío ⇒ lista vacía.
Si A no es vacío ⇒ raíz + preorden(A1) +…+ preorden(Am).
Inorden(A):
Si A es vacío ⇒ lista vacía.
Si A no es vacío ⇒ inorden(A1) + raiz + inorden(A2) +…+ inorden(Am).
Postorden(A):
Si A es vacío ⇒ lista vacía.
Si A no es vacío ⇒ postorden(A1) +…+ postorden(Am) + raíz.
Metodología y Tecnología de la Programación
Tema 11. Árboles
15
11.2 TDA Árbol: Utilización
static public void preOrden(Arbol a) {
preOrden(a,a.raiz());
}
static private void preOrden(Arbol a, Arbol.Nodo n) {
if (a.nulo(n)) return;
System.out.println(a.recupera(n).valor());
Arbol.Nodo m = a.hijoIzquierdo(n);
while (!a.nulo(m)) {
preOrden(a,m);
m = a.hermanoDerecho(m);
}
}
Metodología y Tecnología de la Programación
Tema 11. Árboles
16
11.2 TDA Árbol: Utilización
static public void inOrden(Arbol a) {
inOrden(a,a.raiz());
}
static private void inOrden(Arbol a, Arbol.Nodo n) {
if (a.nulo(n)) return;
Arbol.Nodo m = a.hijoIzquierdo(n);
inOrden(a,m);
System.out.println(a.recupera(n).valor());
while (!a.nulo(m)) {
m = a.hermanoDerecho(m);
inOrden(a,m);
}
}
Metodología y Tecnología de la Programación
Tema 11. Árboles
17
11.2 TDA Árbol: Utilización
static public void postOrden(Arbol a) {
postOrden(a,a.raiz());
}
static private void postOrden(Arbol a, Arbol.Nodo n) {
if (a.nulo(n)) return;
Arbol.Nodo m = a.hijoIzquierdo(n);
while (!a.nulo(m)) {
postOrden(a,m);
m = a.hermanoDerecho(m);
}
System.out.println(a.recupera(n).valor());
}
Metodología y Tecnología de la Programación
Tema 11. Árboles
18
11.2 TDA Árbol: Implementación con representación Enlazada
representación hijo izquierdo - hermano derecho.
mediante apuntadores.
Metodología y Tecnología de la Programación
Tema 11. Árboles
19
11.2 TDA Árbol: Implementación con representación Enlazada
TDA Árbol: Estructura de datos con representación Enlazada.
public class Arbol {
public class Nodo {
private Elemento elemento;
private Nodo padre, hijoIzquierdo, hermanoDerecho;
}
private Nodo raiz;
…
}
Eficiencia:
Todas las operaciones pueden realizarse con tiempos de ejecución O(1).
Excepto las de eliminación de nodos que requieren la eliminación de un
conjunto de nodos.
Estas últimas operaciones pueden realizarse fácilmente de forma recursiva.
Metodología y Tecnología de la Programación
Tema 11. Árboles
20
11.2 TDA Árbol: Implementación con representación Enlazada
public class Arbol {
public class Nodo {
private Elemento elemento;
private Nodo padre, hijoIzquierdo, hermanoDerecho;
}
private Nodo raiz;
public Arbol()
{ raiz = null; }
public Nodo raiz()
{ return raiz; }
public Nodo padre(Nodo n)
{ return n.padre; }
public Nodo hijoIzquierdo(Nodo n) { return n.hijoIzquierdo; }
public Nodo hermanoDerecho(Nodo n) { return n.hermanoDerecho; }
public boolean vacio()
{ return (raiz==null); }
public Elemento recupera(Nodo n)
{ return n.elemento; }
public boolean nulo(Nodo n)
{ return (n==null); }
Metodología y Tecnología de la Programación
Tema 11. Árboles
21
11.2 TDA Árbol: Implementación con representación Enlazada
public void insertaRaiz(Elemento e) {
raiz = new Nodo();
raiz.elemento = e;
raiz.padre = null;
raiz.hijoIzquierdo = null;
raiz.hermanoDerecho = null;
}
public void insertaHijo(Nodo n, Elemento e) {
Nodo aux = new Nodo();
aux.elemento = e;
aux.padre = n;
aux.hijoIzquierdo = null;
aux.hermanoDerecho = n.hijoIzquierdo;
n.hijoIzquierdo = aux;
}
Metodología y Tecnología de la Programación
Tema 11. Árboles
22
11.2 TDA Árbol: Implementación con representación Enlazada
public void insertaHermano(Nodo n, Elemento e) {
Nodo aux = new Nodo();
aux.elemento = e;
aux.padre = n.padre;
aux.hijoIzquierdo = null;
aux.hermanoDerecho = n.hermanoDerecho;
n.hermanoDerecho = aux;
}
public void suprimeHijo(Nodo n) {
n.hijoIzquierdo = n.hijoIzquierdo.hermanoDerecho;
}
public void suprimeHermano(Nodo n) {
n.hermanoDerecho = n.hermanoDerecho.hermanoDerecho;
}
public void modifica(Nodo n, Elemento e) {
n.elemento = e;
}
} // fin class Arbol
Metodología y Tecnología de la Programación
Tema 11. Árboles
23
11.3 TDA Árbol Binario: Descripción
Conjunto de operaciones muy similar al que hemos descrito para el
TDA Árbol.
Las operaciones de posicionamiento, inserción y eliminación van
dirigidas hacia el hijo izquierdo y hacia el hijo derecho.
En el árbol binario, los subárboles se constituyen desde su
creación como subárboles izquierdos o derechos:
En un árbol, un subárbol puede ser creado como subárbol de más
la izquierda y después dejar de serlo.
En un árbol binario las operaciones de eliminación de nodos o
subárboles no provocan cambios en los restantes nodos o
subárboles.
Metodología y Tecnología de la Programación
Tema 11. Árboles
24
11.3 TDA Árbol Binario: Operaciones
Operaciones de construcción:
CREA
Operaciones de posicionamiento:
RAIZ
PADRE
HIJOIZQUIERDO, HIJODERECHO
Operaciones de consulta:
VACIO
RECUPERA
NULO
Operaciones de modificación:
INSERTARAIZ, INSERTAHIJOIZQUIERDO, INSERTAHIJODERECHO
SUPRIMEHIJOIZQUIERDO, SUPRIHIJOMEDERECHO
MODIFICA
Metodología y Tecnología de la Programación
Tema 11. Árboles
25
11.3 TDA Árbol Binario: Especificación
ArbolBinario = TDA con operaciones crea,raiz, padre, hijoIzquierdo,
hijoDerecho, vacio, recupera, nulo, insertaRaiz,
insertaHijoIzquierdo, insertaHijoDerecho, suprimeHijoIzquierdo,
suprimeHijoDerecho, modifica.
DESCRIPCIÓN:
Los valores del TDA ArbolBinario son árboles binarios donde cada nodo contiene un
dato del tipo Elemento. Los nodos son del tipo Nodo. Los árboles son mutables:
insertaRaiz, insertaHijoIzquierdo, insertaHijoDerecho,
suprimeHijoIzquierdo, suprimeHijoDerecho y modifica añaden, eliminan y
modifican respectivamente elementos de un árbol.
OPERACIONES:
crea() devuelve (A:ArbolBinario)
efecto: Devuelve el árbol binario vacío A.
raiz(A:ArbolBinario) devuelve (Nodo)
efecto: Devuelve la raíz de A. Si A es vacío, devuelve nulo.
Metodología y Tecnología de la Programación
Tema 11. Árboles
26
11.3 TDA Árbol Binario: Especificación
padre(A:ArbolBinario; N:Nodo) devuelve (Nodo)
requerimientos: N ≠ nulo.
efecto: Devuelve el padre de N. Si N es la raíz de A, devuelve nulo.
hijoIzquierdo(A:ArbolBinario; N:Nodo) devuelve (Nodo)
requerimientos: N ≠ nulo.
efecto: Devuelve el hijo izquierdo de N. Si N no tiene hijo izquierdo, devuelve nulo.
hijoDerecho(A:ArbolBinario; N:Nodo) devuelve (Nodo)
requerimientos: N ≠ nulo.
efecto: Devuelve el hijo derecho de N. Si N no tiene hijo derecho, devuelve nulo.
vacio(A:ArbolBinario) devuelve (booleano)
efecto: Devuelve cierto si A es vacío, y falso en caso contrario.
recupera(A:ArbolBinario; N:Nodo) devuelve (Elemento)
requerimientos: N ≠ nulo.
efecto: Devuelve el contenido de N.
Metodología y Tecnología de la Programación
Tema 11. Árboles
27
11.3 TDA Árbol Binario: Especificación
nulo(A:ArbolBinario; N:Nodo) devuelve (booleano)
efecto: Devuelve cierto si N es nulo, y falso en caso contrario.
insertaRaiz(A:ArbolBinario; E:Elemento)
requerimientos: A = vacío.
modifica: A.
efecto: Añade un nodo, con contenido E, como raíz de A como raíz de A.
insertaHijoIzquierdo(A:ArbolBinario; N:Nodo; E:Elemento)
requerimientos: N ≠ nulo y hijoIzquierdo(N) = nulo.
modifica: A.
efecto: Añade un nodo, con contenido E, como hijo izquierdo de N.
insertaHijoDerecho(A:ArbolBinario; N:Nodo; E:Elemento)
requerimientos: N ≠ nulo. hijoDerecho(N) = nulo.
modifica: A.
efecto: Añade un nodo, con contenido E, como hijo derecho de N.
Metodología y Tecnología de la Programación
Tema 11. Árboles
28
11.3 TDA Árbol Binario: Especificación
suprimeHijoIzquierdo(A:ArbolBinario; N:Nodo)
requerimientos: N ≠ nulo. hijoIzquierdo(N) ≠ nulo.
modifica: A.
efecto: Suprime el hijo izquierdo de N y todos sus descendientes.
suprimeHijoDerecho(A:ArbolBinario; N:Nodo)
requerimientos: N ≠ nulo. hijoDerecho(N) ≠ nulo.
modifica: A.
efecto: Suprime el hijo derecho de N y todos sus descendientes.
modifica(A:ArbolBinario; N:Nodo; E:Elemento)
requerimientos: N ≠ nulo.
modifica: A.
efecto: Modifica el contenido de N cambiándolo por el nuevo contenido E.
Metodología y Tecnología de la Programación
Tema 11. Árboles
29
11.3 TDA Árbol Binario: Métodos en Java
Clase ArbolBinario
class ArbolBinario
Clases Internas
class ArbolBinario.Nodo
Constructores
ArbolBinario()
Métodos
ArbolBinario.Nodo raiz()
ArbolBinario.Nodo padre(ArbolBinario.Nodo n)
ArbolBinario.Nodo hijoIzquierdo(ArbolBinario.Nodo n)
ArbolBinario.Nodo hijoDerecho(ArbolBinario.Nodo n)
boolean vacio()
Elemento recupera(ArbolBinario.Nodo n)
boolean nulo(ArbolBinario.Nodo n)
void insertaRaiz(Elemento e)
void insertaHijoIzquierdo(ArbolBinario.Nodo n, Elemento e)
void insertaHijoDerecho(ArbolBinario.Nodo n, Elemento e)
void suprimeHijoIzquierdo(ArbolBinario.Nodo n)
void suprimeHijoDerecho(ArbolBinario.Nodo n)
void modifica(ArbolBinario.Nodo n, Elemento e)
Metodología y Tecnología de la Programación
Tema 11. Árboles
30
11.3 TDA Árbol Binario: Esquemas de Recorrido
Esquemas de recorrido en árboles binarios:
Preorden(A):
Si A es vacío ⇒ lista vacía.
Si A no es vacío ⇒ raíz + preorden(A1) + preorden(A2).
Inorden(A):
Si A es vacío ⇒ lista vacía.
Si A no es vacío ⇒ inorden(A1) + raiz + inorden(A2).
Postorden(A):
Si A es vacío ⇒ lista vacía.
Si A no es vacío ⇒ postorden(A1) + postorden(A2) + raíz.
Metodología y Tecnología de la Programación
Tema 11. Árboles
31
11.3 TDA Árbol Binario: Utilización
static public void preOrden(ArbolBinario a) { preOrden(a,a.raiz()); }
static private void preOrden(ArbolBinario a, ArbolBinario.Nodo n) {
if (a.nulo(n)) return;
System.out.println(a.recupera(n).valor());
preOrden(a,a.hijoIzquierdo(n));
preOrden(a,a.hijoDerecho(n)); }
static public void inOrden(ArbolBinario a) { inOrden(a,a.raiz()); }
static private void inOrden(ArbolBinario a, ArbolBinario.Nodo n) {
if (a.nulo(n)) return;
inOrden(a,a.hijoIzquierdo(n));
System.out.println(a.recupera(n).valor());
inOrden(a,a.hijoDerecho(n)); }
static public void postOrden(ArbolBinario a) {
postOrden(a,a.raiz()); }
static private void postOrden(ArbolBinario a, ArbolBinario.Nodo n) {
if (a.nulo(n)) return;
postOrden(a,a.hijoIzquierdo(n));
postOrden(a,a.hijoDerecho(n));
System.out.println(a.recupera(n).valor()); }
Metodología y Tecnología de la Programación
Tema 11. Árboles
32
11.3 TDA Árbol Binario:
Implementación con representación Enlazada
representación hijo izquierdo - hijo derecho.
mediante apuntadores.
Metodología y Tecnología de la Programación
Tema 11. Árboles
33
11.3 TDA Árbol Binario:
Implementación con representación Enlazada
TDA Árbol: Estructura de datos con representación Enlazada.
public class ArbolBinario {
public class Nodo {
private Elemento elemento;
private Nodo padre, hijoIzquierdo, hijoDerecho;
}
private Nodo raiz;
…
}
Eficiencia:
Todas las operaciones pueden realizarse con tiempos de ejecución O(1).
Metodología y Tecnología de la Programación
Tema 11. Árboles
34
11.3 TDA Árbol Binario:
Implementación con representación Enlazada
public class ArbolBinario {
public class Nodo {
private Elemento elemento;
private Nodo padre, hijoIzquierdo, hijoDerecho;
}
private Nodo raiz;
public ArbolBinario()
{ raiz = null; }
public Nodo raiz()
{ return raiz; }
public Nodo padre(Nodo n)
{ return n.padre; }
public Nodo hijoIzquierdo(Nodo n) { return n.hijoIzquierdo; }
public Nodo hijoDerecho(Nodo n)
{ return n.hijoDerecho; }
public boolean vacio()
{ return (raiz==null); }
public Elemento recupera(Nodo n) { return n.elemento; }
public boolean nulo(Nodo n)
{ return (n==null); }
Metodología y Tecnología de la Programación
Tema 11. Árboles
35
11.3 TDA Árbol Binario:
Implementación con representación Enlazada
public void insertaRaiz(Elemento e) {
raiz = new Nodo();
raiz.elemento = e;
raiz.padre = null;
raiz.hijoIzquierdo = null;
raiz.hijoDerecho = null;
}
public void insertaHijoIzquierdo(Nodo n, Elemento e) {
n.hijoIzquierdo = new Nodo();
n.hijoIzquierdo.elemento = e;
n.hijoIzquierdo.padre = n;
n.hijoIzquierdo.hijoIzquierdo = null;
n.hijoIzquierdo.hijoDerecho = null;
}
Metodología y Tecnología de la Programación
Tema 11. Árboles
36
11.3 TDA Árbol Binario:
Implementación con representación Enlazada
public void insertaHijoDerecho(Nodo n, Elemento e) {
n.hijoDerecho = new Nodo();
n.hijoDerecho.elemento = e;
n.hijoDerecho.padre = n;
n.hijoDerecho.hijoIzquierdo = null;
n.hijoDerecho.hijoDerecho = null;
}
public void suprimeHijoIzquierdo(Nodo n) {
n.hijoIzquierdo = null; }
public void suprimeHijoDerecho(Nodo n) {
n.hijoDerecho = null; }
public void modifica(Nodo n, Elemento e) {
n.elemento = e; }
} // fin class ArbolBinario
Metodología y Tecnología de la Programación
Tema 11. Árboles
37
11.4 TDA Árbol basado en su Definición Recursiva
TDA Árbol: Especificación Formal.
Tipo: Arbol (Elemento)
Sintaxis:
arbolvacio → Arbol
arbolcompleto(Lista,Elemento) → Arbol
vacio(Arbol) → booleano
raiz(Arbol) → Elemento
subarboles(Arbol) → Lista
Semántica: ∀ L ∈ Lista, ∀ E ∈ Elemento:
vacio(arbolvacio) ⇒ cierto
vacio(arbolcompleto(L,E)) ⇒ falso
raiz(arbolvacio) ⇒ error
raiz(arbolcompleto(L,E)) ⇒ E
subarboles(arbolvacio) ⇒ error
subarboles(arbolcompleto(L,E)) ⇒ L
Metodología y Tecnología de la Programación
Tema 11. Árboles
38
11.4 TDA Árbol basado en su Definición Recursiva
TDA Lista de Árboles: Especificación Formal.
Tipo: Lista (Arbol)
Sintaxis:
listavacia → Lista
inserta(Lista,Arbol) → Lista
vacia(Lista) → booleano
cabeza(Lista) → Arbol
resto(Lista) → Lista
Semántica: ∀ L ∈ Lista, ∀ A ∈ Arbol:
vacia(listavacia) ⇒ cierto
vacia(inserta(L,A)) ⇒ falso
cabeza(listavacia) ⇒ error
cabeza(inserta(L,A)) ⇒ A
resto(listavacia) ⇒ error
resto(inserta(L,A)) ⇒ L
Metodología y Tecnología de la Programación
Tema 11. Árboles
39
11.4 TDA Árbol basado en su Definición Recursiva
Clase Arbol
class Arbol
Clase Lista
class Lista
Constructores
Arbol()
Arbol(Lista l, Elemento e)
Constructores
Lista()
Lista(Lista l, Arbol a)
Métodos
boolean vacio()
Elemento raiz()
Lista subarboles()
Métodos
boolean vacia()
Arbol cabeza()
Lista resto()
Metodología y Tecnología de la Programación
Tema 11. Árboles
40
11.4 TDA Árbol basado en su Definición Recursiva
Utilización del Árbol Inmutable: Recorrido en Pre-Orden
static public void preOrden(Arbol a) {
if (a.vacio()) return;
System.out.println(a.raiz().valor());
lista_preOrden(a.subarboles());
}
static private void lista_preOrden(Lista l) {
if (l.vacia()) return;
preOrden(l.cabeza());
lista_preOrden(l.resto());
}
Metodología y Tecnología de la Programación
Tema 11. Árboles
41
11.4 TDA Árbol basado en su Definición Recursiva
Utilización del Árbol Inmutable: Recorrido en In-Orden
static public void inOrden(Arbol a) {
if (a.vacio()) return;
Lista l = a.subarboles();
if (!l.vacia()) inOrden(l.cabeza());
System.out.println(a.raiz().valor());
if (!l.vacia()) lista_inOrden(l.resto());
}
static private void lista_inOrden(Lista l) {
if (l.vacia()) return;
inOrden(l.cabeza());
lista_inOrden(l.resto());
}
Metodología y Tecnología de la Programación
Tema 11. Árboles
42
11.4 TDA Árbol basado en su Definición Recursiva
Utilización del Árbol Inmutable: Recorrido en Post-Orden
static public void postOrden(Arbol a) {
if (a.vacio()) return;
lista_postOrden(a.subarboles());
System.out.println(a.raiz().valor());
}
static private void lista_postOrden(Lista l) {
if (l.vacia()) return;
postOrden(l.cabeza());
lista_postOrden(l.resto());
}
Metodología y Tecnología de la Programación
Tema 11. Árboles
43
11.4 TDA Árbol basado en su Definición Recursiva
Implementación del Árbol Inmutable Recursivo
public class Arbol {
private Elemento elemento;
private Lista subarboles;
public Arbol() { elemento=null; subarboles=null; }
public Arbol(Lista l, Elemento e) { elemento=e; subarboles=l; }
public boolean vacio(){
return ((elemento==null)&&(subarboles==null)); }
public Elemento raiz() { return elemento; }
public Lista subarboles() { return subarboles; }
} // fin class Arbol
public class Lista {
private Arbol arbol;
private Lista sig;
public Lista() { arbol=null; sig=null; }
public Lista(Lista l, Arbol a) { arbol=a; sig=l; }
public boolean vacia() { return ((arbol==null)&&(sig==null)); }
public Arbol cabeza() { return arbol; }
public Lista resto() { return sig; }
} // fin class Lista
Metodología y Tecnología de la Programación
Tema 11. Árboles
44
11.5 TDA Árbol Binario basado en su Definición Recursiva
TDA Árbol Binario: Especificación Formal.
Tipo: ArbolBinario (Elemento)
Sintaxis:
arbolvacio → ArbolBinario
arbolcompleto(Arbolbinario,Arbolbinario,Elemento) → ArbolBinario
vacio(ArbolBinario) → booleano
raiz(ArbolBinario) → Elemento
subarbolIzquierdo(ArbolBinario) → ArbolBinario
subarbolDerecho(ArbolBinario) → ArbolBinario
Semántica: ∀ A1,A2 ∈ ArbolBinario, ∀ E ∈ Elemento:
vacio(arbolvacio) ⇒ cierto
vacio(arbolcompleto(A1,A2,E)) ⇒ falso
raiz(arbolvacio) ⇒ error
raiz(arbolcompleto(A1,A2,E)) ⇒ E
subarbolIzquierdo(arbolvacio) ⇒ error
subarbolIzquierdo(arbolcompleto(A1,A2,E)) ⇒ A1
subarbolDerecho(arbolvacio) ⇒ error
subarbolDerecho(arbolcompleto(A1,A2,E)) ⇒ A2
Metodología y Tecnología de la Programación
Tema 11. Árboles
45
11.5 TDA Árbol Binario basado en su Definición Recursiva
TDA Árbol Binario Inmutable: Métodos en Java.
Clase ArbolBinario
class ArbolBinario
Constructores
ArbolBinario()
ArbolBinario(ArbolBinario a1, ArbolBinario a2, Elemento e)
Métodos
boolean vacio()
Elemento raiz()
ArbolBinario subarbolIzquierdo()
ArbolBinario subarbolDerecho()
Metodología y Tecnología de la Programación
Tema 11. Árboles
46
11.5 TDA Árbol Binario basado en su Definición Recursiva
Utilización del Árbol Binario Inmutable
static public void preOrden(ArbolBinario a) {
if (a.vacio()) return;
System.out.println(a.raiz().valor());
preOrden(a.subarbolIzquierdo());
preOrden(a.subarbolDerecho());
}
static public void inOrden(ArbolBinario a) {
if (a.vacio()) return;
inOrden(a.subarbolIzquierdo());
System.out.println(a.raiz().valor());
inOrden(a.subarbolDerecho());
}
static public void postOrden(ArbolBinario a) {
if (a.vacio()) return;
postOrden(a.subarbolIzquierdo());
postOrden(a.subarbolDerecho());
System.out.println(a.raiz().valor());
}
Metodología y Tecnología de la Programación
Tema 11. Árboles
47
11.5 TDA Árbol Binario basado en su Definición Recursiva
Implementación del Árbol Inmutable
public class ArbolBinario {
private Elemento elemento;
private ArbolBinario izquierdo,derecho;
public ArbolBinario() {
elemento=null; izquierdo=null; derecho=null;
}
public ArbolBinario(ArbolBinario a1, ArbolBinario a2, Elemento e) {
elemento=e; izquierdo=a1; derecho=a2;
}
public boolean vacio() {
return((elemento==null)&&(izquierdo==null)&&(derecho==null));
}
public Elemento raiz() { return elemento; }
public ArbolBinario subarbolIzquierdo() { return izquierdo; }
public ArbolBinario subarbolDerecho() { return derecho; }
} // fin class ArbolBinario
Metodología y Tecnología de la Programación
Tema 11. Árboles
48
11.6 Árboles Parcialmente Ordenados: Colas de Prioridad
Operación
Árbol binario
inserta
O(n)
O(log n)
suprime
O(1)
O(log n)
Balanceado:
Estructura lineal
Todas las hojas tienen profundidad ⌊log n⌋ ó ⌊log n⌋ − 1.
Las hojas que faltan son las de más a la derecha posible.
Parcialmente ordenado:
La prioridad de un nodo no es menor que la de sus hijos.
⇒ En la raíz estará siempre el elemento con mayor prioridad.
Metodología y Tecnología de la Programación
Tema 11. Árboles
49
11.6 Árboles Parcialmente Ordenados: Colas de Prioridad
Representación por montículos
Vector:
A[1] contiene la raíz.
el hijo izquierdo de A[i] está, si existe, en A[2i].
el hijo derecho de A[i] está, si existe, en A[2i + 1].
el padre de A[i] está en A[i div 2], para i > 1.
Ventajas:
Se opera aritméticamente con los índices del vector para obtener, con
tiempos de ejecución constantes, las posiciones de los padres e hijos
izquierdo y derecho.
Desventajas:
Se requiere determinar a priori el número máximo de elementos en el
árbol.
Metodología y Tecnología de la Programación
Tema 11. Árboles
50
11.6 Árboles Parcialmente Ordenados: Colas de Prioridad
public class ColaPrioridad {
private Elemento elementos[];
private int prioridades[];
private int ultimo;
public ColaPrioridad() {
elementos = new Elemento[100];
prioridades = new int[100];
ultimo = 0;
}
public boolean vacia() { return (ultimo==0); }
public Elemento primero() { return elementos[1]; }
Metodología y Tecnología de la Programación
Tema 11. Árboles
51
11.6 Árboles Parcialmente Ordenados: Colas de Prioridad
Metodología y Tecnología de la Programación
Tema 11. Árboles
52
11.6 Árboles Parcialmente Ordenados: Colas de Prioridad
public void inserta(Elemento e, int prioridad) {
ultimo++;
int i = ultimo;
while(i>1) {
int padre = i/2;
if (prioridad<=prioridades[padre]) break;
elementos[i] = elementos[padre];
prioridades[i] = prioridades[padre];
i = padre;
}
elementos[i] = e;
prioridades[i] = prioridad;
}
Metodología y Tecnología de la Programación
Tema 11. Árboles
53
11.6 Árboles Parcialmente Ordenados: Colas de Prioridad
Metodología y Tecnología de la Programación
Tema 11. Árboles
54
11.6 Árboles Parcialmente Ordenados: Colas de Prioridad
public void suprime() {
Elemento e = elementos[ultimo];
int prioridad = prioridades[ultimo];
ultimo--;
int i = 1;
int hijo = 2*i;
while(hijo<=ultimo) {
if ((hijo<ultimo)&&(prioridades[hijo]<prioridades[hijo+1]))
hijo++;
if (prioridad>=prioridades[hijo]) break;
elementos[i] = elementos[hijo];
prioridades[i] = prioridades[hijo];
i = hijo;
hijo = 2*i;
}
elementos[i] = e;
prioridades[i] = prioridad;
}
} // fin class ColaPrioridad
Metodología y Tecnología de la Programación
Tema 11. Árboles
55
11.7 Árboles Binarios de Búsqueda: Conjuntos
Árbol binario de búsqueda
Los elementos del subárbol izquierdo de cualquier nodo son menores
que el elemento de dicho nodo.
Los elementos almacenados en el subárbol derecho de cualquier nodo
son mayores que el elemento almacenado en ese nodo.
Metodología y Tecnología de la Programación
Tema 11. Árboles
56
11.7 Árboles Binarios de Búsqueda: Conjuntos
Representación de Conjuntos:
inserta: inserta un elemento en un conjunto.
suprime: suprime un elemento de un conjunto.
pertenece: indica si un elemento dado pertenece o no a un conjunto).
⇒ Tiempo de ejecución promedio O(log n).
Otras operaciones: (Colas de Prioridad)
min: devuelve el elemento mínimo de un árbol.
suprime_min: elimina el elemento mínimo de un árbol.
max: devuelve el elemento máximo de un árbol.
suprime_max: elimina el elemento máximo de un árbol.
⇒ Tiempo de ejecución promedio O(log n).
⇒ Tiempo de ejecución peor caso O(n).
⇒ Tiempo de ejecución peor caso O(log n), si balanceado (árboles AVL,
árboles B, etc.)
Metodología y Tecnología de la Programación
Tema 11. Árboles
57
11.7 Árboles Binarios de Búsqueda: Conjuntos
public class Conjunto {
private Elemento elemento;
private Conjunto izquierdo, derecho;
public Conjunto() {
elemento = null;
izquierdo = null;
derecho = null;
}
public boolean vacio() {
return ((elemento==null)&&(izquierdo==null)&&(derecho==null));
}
public boolean pertenece(Elemento e) {
if (vacio()) return false;
else if (e.valor()>elemento.valor())
return derecho.pertenece(e);
else if (e.valor()<elemento.valor())
return izquierdo.pertenece(e);
return true;
}
Metodología y Tecnología de la Programación
Tema 11. Árboles
58
11.7 Árboles Binarios de Búsqueda: Conjuntos
public void inserta(Elemento e) {
if (vacio()) {
elemento = e;
izquierdo = new Conjunto();
derecho = new Conjunto();
}
else if (e.valor()>elemento.valor())
derecho.inserta(e);
else if (e.valor()<elemento.valor())
izquierdo.inserta(e);
}
Metodología y Tecnología de la Programación
Tema 11. Árboles
59
11.7 Árboles Binarios de Búsqueda: Conjuntos
Operación suprime:
1. Localiza la posición del nodo a suprimir:
⇒ Realizando una búsqueda similar a la realizada por la operación
miembro.
2. Elimina el nodo:
a) Si el nodo no tiene hijos ⇒ suprime el nodo.
b) Si tiene hijo derecho:
⇒ suprime el nodo.
⇒ sustituye el nodo por su hijo derecho.
c) Si tiene hijo izquierdo:
⇒ suprime el nodo.
⇒ sustituye el nodo por su hijo derecho.
d) Si tiene hijos derecho e izquierdo:
⇒ encuentra el menor elemento de los descendientes del hijo derecho (NOTA:
otra alternativa es encontrar el mayor elemento de los descendientes del hijo
izquierdo).
⇒ suprime el nodo de dicho elemento.
⇒ sustituye el nodo por dicho elemento.
Metodología y Tecnología de la Programación
Tema 11. Árboles
60
11.7 Árboles Binarios de Búsqueda: Conjuntos
public void suprime(Elemento e) {
if (e.valor()>elemento.valor()) derecho.suprime(e);
else if (e.valor()<elemento.valor())
izquierdo.suprime(e);
else if ((izquierdo.vacio())&&(derecho.vacio())) {
elemento = null;
derecho = null;
izquierdo = null; }
else if (izquierdo.vacio()) {
elemento = derecho.elemento;
izquierdo = derecho.izquierdo;
derecho = derecho.derecho; }
else if (derecho.vacio()) {
elemento = izquierdo.elemento;
derecho = izquierdo.derecho;
izquierdo = izquierdo.izquierdo; }
Metodología y Tecnología de la Programación
Tema 11. Árboles
61
11.7 Árboles Binarios de Búsqueda: Conjuntos
else {
Conjunto min = derecho;
while (!min.izquierdo.vacio()) min = min.izquierdo;
elemento = min.elemento;
min.elemento = min.derecho.elemento;
min.izquierdo = min.derecho.izquierdo;
min.derecho = min.derecho.derecho;
}
}
} // fin class Conjunto
Metodología y Tecnología de la Programación
Tema 11. Árboles
62