Download Árboles

Document related concepts

Árbol binario wikipedia , lookup

Recorrido de árboles wikipedia , lookup

Árbol binario de búsqueda wikipedia , lookup

Árbol-B wikipedia , lookup

Árbol de intervalo wikipedia , lookup

Transcript
Algoritmos y Lenguaje de Programación,
Sección 1
Árboles
Árboles
• Árboles
• Estructura recursiva
)Árbol vacío
)0 o más árboles hijos
Mario Medina C.
[email protected]
• Altura ilimitada
• Árbol binario
)A lo más dos hijos: izquierdo y derecho
Árboles
Árboles binarios de búsqueda
20
Raíz
12
• Árbol binario de búsqueda
• Cada nodo almacena un valor
25
16
28
5
14
9
17
15
26
Hojas
29
Hojas
Árbol binario de búsqueda
20
<
12
<
5
Inserción en un árbol
• Si árbol está vacío
Raíz
)Insertar valor como nodo raíz
>
25
• Caso contrario
>
>
16
28
>
>
9
17
<
)Si nuevo valor es menor que valor del nodo actual
` Insertar nuevo valor en el subárbol a la izquierda del
nodo actual
>
26
29
Hojas
©Mario Medina C.
)mayor que todos los valores almacenados en el
subárbol izquierdo
)menor que todos los valores almacenados en el
subárbol derecho
)No almacena valores duplicados
)Ideales para búsqueda
)Si nuevo valor es mayor que valor del nodo actual
` Insertar nuevo valor en el subárbol a la derecha del
valor actual
1
Algoritmos y Lenguaje de Programación,
Sección 1
Inserción
Remoción en un árbol
20
12
5
• Nodo sin hijos
Raíz
)Eliminación directa
• Nodo con un nodo hijo
25
)Nodo padre hereda al nodo hijo
• Nodo con dos hijos
28
16
)Buscar el nodo de mayor valor en el hijo izquierdo
9
15
17
26
Hojas
29
Hojas
Búsqueda en un árbol
Remover raíz
17
• Búsqueda en árboles binarios es rápida
Raíz
12
5
1. Comparar valor buscado con la raíz
` Si es igual, algoritmo termina
25
15
17
26
Hojas
29
• Varias formas de recorrer un árbol
) Pre-orden
1. Visita primero la raíz
2. Luego el subárbol izquierdo
3. Finalmente, el subárbol derecho
) Post-orden
1. Visita primero el subárbol izquierdo
2. Luego el subárbol derecho
3. Finalmente, visita la raíz
• Algoritmo iterativo o recursivo!
Hojas
Recorrido de un árbol
©Mario Medina C.
2. Si valor de la raíz es mayor que valor buscado,
buscar en subárbol izquierdo
3. Si valor de la raíz es menor que el valor buscado,
buscar en subárbol derecho
28
16
9
` Reemplazar el valor del nodo raíz por mayor valor
` Eliminar el nodo de mayor valor
Recorrido de un árbol
) In-orden
1. Visita primero el subárbol izquierdo
2. Luego la raíz
3. Finalmente, el subárbol derecho
) Por niveles
1.
2.
3.
4.
Visita primero la raíz
Luego los dos hijos de la raíz
Luego los dos hijos de cada hijo de la raíz
Luego los hijos de éstos, y así hasta llegar a las hojas
2
Algoritmos y Lenguaje de Programación,
Sección 1
Ejemplos de recorridos
Ejemplos de recorridos
20
12
5
• Pre-Orden
Raíz
)20, 12, 5, 9, 16, 17, 25, 28, 26, 29
• In-Orden
25
)5, 9, 12, 16, 17, 20, 25, 26, 28, 29
• Post-Orden
28
16
)9, 5, 17, 16, 12, 26, 29, 28, 25, 20
9
17
26
Hojas
29
Hojas
Implementación de árboles
/* Estructura para un nodo */
typedef struct NODOARBOL {
int valor;
struct NODOARBOL *izq;
struct NODOARBOL *der;
} NodoArbol;
/* Raiz del arbol */
NodoArbol *raiz;
Inserción iterativa (1)
void inserta(NodoArbol *raiz, int valor) {
NodoArbol *nodo, **temp;
temp = &raiz;
while((nodo = *temp) != NULL) {
if(valor < nodo->valor)
temp = &nodo->izq;
else
temp = &nodo->der;
}
/* Continúa */
©Mario Medina C.
• Por Niveles
)20, 12, 25, 5, 16, 28, 9, 17, 26, 29
Búsqueda iterativa
int *buscar(NodoArbol *nodo, int valor) {
while(nodo != NULL && nodo->valor != valor) {
if (valor < nodo->valor)
nodo = nodo->izq;
else
nodo = nodo->der;
}
if (nodo != NULL)
return TRUE;
else
return FALSE;
}
Inserción iterativa (2)
nodo = malloc(sizeof(NodoArbol));
assert(nodo != NULL);
nodo->valor = valor;
nodo->izq = NULL;
nodo->der = NULL;
*temp = nodo;
}
3
Algoritmos y Lenguaje de Programación,
Sección 1
Búsqueda recursiva
int *buscar(NodoArbol *nodo, int valor) {
if (nodo == NULL)
return FALSE;
if (nodo->valor == valor)
return TRUE;
if (nodo->valor > valor)
return buscar(nodo->izq, valor);
else
return buscar(nodo->der, valor);
}
Inserción recursiva (2)
if (valor < nodo->valor)
nodo->izq = insertar(nodo->izq, valor);
else
nodo->der = insertar(nodo->der, valor);
}
Inserción recursiva (1)
NodoArbol *insertar(NodoArbol *nodo, int
valor) {
NodoArbol *temp;
if (nodo == NULL) {
temp = malloc(sizeof(NodoArbol));
temp->izq = NULL;
temp->der = NULL;
temp->valor = valor;
return temp;
}
/* Continúa */
Tamaño de un árbol
• Calcula el número de nodos de un árbol
int tamano(NodoArbol *nodo) {
if (nodo == NULL)
return 0;
return tamano(nodo->izq) + 1 +
tamano(nodo->der);
return nodo;
}
/* Funcion retorna puntero a nueva raiz */
}
Profundidad de un árbol
Mínimo valor en un árbol
• Calcula camino más largo en un árbol
• Encuentra el valor mínimo en un árbol
int profundidad(NodoArbol *nodo) {
int profIzq, profDer;
if (nodo == NULL)
return 0;
profIzq = profundidad(nodo->izq);
profDer = profundidad(nodo->der);
return (profIzq > profDer) ?
profIzq + 1 : profDer + 1;
}
©Mario Medina C.
)No se requiere revisar todo el árbol
)Sólo revisar los hijos izquierdos
int minValor(NodoArbol *nodo) {
NodoArbol *actual = nodo;
if (actual == NULL)
return 0;
while (actual->izq != NULL)
actual = actual->izq;
return actual->dato;
}
4
Algoritmos y Lenguaje de Programación,
Sección 1
Imprimir un árbol
Imprimir un árbol en post-orden
• Imprime el árbol en in-orden
• Imprime el árbol en post-orden
)Orden creciente de los valores
void imprime(NodoArbol *nodo) {
if (nodo == NULL)
return;
imprime(nodo->izq);
printf(“%d ”, nodo->valor);
imprime(nodo->der);
}
Orden de operaciones en un árbol
void imprime(NodoArbol *nodo) {
if (nodo == NULL)
return;
imprime(nodo->izq);
imprime(nodo->der);
printf(“%d ”, nodo->valor);
}
Búsqueda binaria
• Buscar en un árbol de búsqueda binario es
orden O(log2 n)
• Cada nodo visitado desde la raíz divide el
árbol en dos
)1 nodo → 2 divisiones
)2 nodos → 4 divisiones
)3 nodos → 8 divisiones
)4 nodos → 16 divisiones
20
Raíz
12
5
25
28
16
9
17
26
Hojas
29
Hojas
Orden: árbol de búsqueda binario
Orden de operaciones en un árbol
• Buscar un elemento: O(log n)
• Insertar un elemento: O(n)
• Encontrar el tamaño del árbol: O(n)
• Encontrar la profundidad del árbol: O(n)
• Encontrar menor elemento: O(log n)
• Imprimir el árbol: O(n)
Y si el árbol no está balanceado?
• Peor caso: Buscar en un árbol es orden O(n)
©Mario Medina C.
)Árbol binario no está necesariamente balanceado
12
16
17
18
5
Algoritmos y Lenguaje de Programación,
Sección 1
Árboles balanceados
Árboles B (B-Trees)
• Garantizan comportamiento O(log n)
• Árboles n-arios balanceados
)Código de operaciones típicas es más complejo
` Más eficientes si se opera sobre muchos datos
)Árboles AVL
` Diferencia entre altura de árboles hijos es a lo más 1
)Árboles Rojo-Negro
` Camino más largo es a los más dos veces el camino
más corto
)Árboles 2-3
)Usados en sistemas de archivos y bases de datos
)Optimizados para sistemas donde sólo una parte
del árbol puede residir en memoria principal
` El resto del árbol se almacena en disco
)Nodos pueden tener un número variable de hijos
)Todas las hojas del árbol están a la misma altura
` Operaciones de inserción y remoción son O(log n)
` Log2 n < altura < Log3 n
©Mario Medina C.
6