2. CAPITULO 8
1. Árboles en general
Definiciones
Terminología
1. Recorrido de árboles
Postorden
Preorden
1. Tipos de árboles
Binarios
AVL
Multicamino
Balanceado (B, B*, B+)
e
br
c tu
O
12
LUIS F. AGUAS B. 2
20
3. ÁRBOL: DEFINICIÓN
En computación, un
árbol es un modelo Computadores
abstracto de una
estructura ventas Manufactura Reclamo
jerárquica.
Local Internacional Laptops Desktops
Aplicaciones:
Organigramas
Sistemas de archivos Europa Asia Canada
Ambientes de
programación
e
br
c tu
O
12
LUIS F. AGUAS B. 3
20
4. ÁRBOLES EN GENERAL Y CON
RAÍZ
En teoría de grafos, un árbol (tree) es un conjunto de nodos
(vértices) y arcos (links, lines) conectando los nodos tal que:
No existen ciclos
cada dos nodos están conectados por un solo arco
En muchas aplicaciones informáticas, un nodo particular del el
árbol es designado raíz (root), los otros nodos son arreglados
por niveles a partir del nodo raíz.
root
Nivel 0
Nivel 1
Nivel 2
Árbol general
br
e Un árbol con raíz
u
ct
O
12
LUIS F. AGUAS B. 4
20
5. TERMINOLOGÍA DE ÁRBOLES
Una estructura de árbol es una colección de nodos, c/u con:
Puede tener uno o mas sucesores
Tiene solo un predecesor, con excepción del nodo raíz.
El nodo primero o inicial de la estructura árbol es llamado
raíz
Un nodo predecesor es llamado padre (parent)
Un nodo sucesor es llamado hijo (children)
Nodos con padre común son llamados hermanos (siblings)
Un nodo sin hijos es llamado hoja (leaf)
Un nodo que tiene hijos es llamado nodo interior
Un nodo sin hijos es llamado nodo exterior
Los nodos descendientes consisten en hijos, nietos hasta llegar
a las hojas.
Los nodos ancestros consisten de padres, abuelos hasta llegar a
e
br la raíz.
c tu
O
12
LUIS F. AGUAS B. 5
20
6. TERMINOLOGÍA DE ÁRBOLES
Un lado (edge or branch) es la línea que conecta un padre
con el hijo.
Un camino (path) es la secuencia de lados que conectan un
nodo con uno de sus descendientes
La longitud del camino (path length) es el número de lados
en el camino.
La profundidad o nivel (depth o level) de un nodo es igual a la
longitud de nodo a la raíz.
La profundidad de la raíz es cero
El peso (height) de un árbol es igual a la longitud del camino
más largo.
Un sub-árbol (subtree) es un árbol formado al considerar un
nodo como “raíz”. El nuevo árbol consiste de este nodo y su
descendencia.
2012 Octubre LUIS F. AGUAS B. 6
7. Terminología de árboles
PROPIEDAD VALOR
Numero de nodos 10
H
Peso 3
Nodo raíz H
B F
Hojas ACJL
MN
A C J E Nodos interiores HBFE
Nodos a nivel 2 ACJE
L M N
2012 Octubre LUIS F. AGUAS B. 7
8. NODO DE ÁRBOL
La clase TreeNode
Representa un node de un árbol
Es similar al Nodo de lista doble (left y right)
public class TreeNode
{ Referencia al hijo
private Object value; izquierdo
private TreeNode left;
private TreeNode right; Referencia al hijo
... derecho
e
br
c tu
O
12
LUIS F. AGUAS B. 8
20
9. LA CLASE TREENODE 2
... ... ...
// Constructores:
public TreeNode (Object v)
{ value = v; left = null; right = null; }
public TreeNode (Object v, TreeNode lt, TreeNode rt)
{ value = v; left = lt; right = rt; }
// Métodos:
public Object getValue () { return value; }
public TreeNode getLeft () { return left; }
public TreeNode getRight () { return right; }
public void setValue (Object v) { value = v; }
public void setLeft (TreeNode lt) { left = lt; }
public void setRight (TreeNode rt) { right = rt; }
e
} tu
br
c
O
12
LUIS F. AGUAS B. 9
20
10. TREENODE EJEMPLO 1
public int countNodes (TreeNode root)
{
if (root == null) Caso base
return 0;
else
return 1 + countNodes ( root.getLeft ( ) ) +
countNodes ( root.getRight ( ) );
}
Para root
e
br
c tu
O
12
LUIS F. AGUAS B. 10
20
11. ÁRBOLES Y RECURSIÓN
La estructura árbol es recursiva por
naturaleza, los lados derechos e izquierdo
son árboles también.
public void traverse (TreeNode root)
{
if (root != null)
{
visit (root);
for (... <each child of the root> )
traverse (< that child’s subtree>);
}
}
e
br
c tu
O
12
LUIS F. AGUAS B. 11
20
12. RECORRIDO PREORDEN
Preorden: primero visita la raíz, entonces
atraviesa la izquierda, y luego atraviesa el
subarbol derecho
private void traversePreorder (TreeNode root) A
{ /
if (root != null) B C
{ /
visit (root.getValue()); D E
traversePreorder (root.getLeft());
traversePreorder (root.getRight()); ABDEC
}
}
e
br
c tu
O
12
LUIS F. AGUAS B. 12
20
13. RECORRIDO POSORDEN
Posorden: primero atraviesa la izquierda
entonces atraviesa el subarbol izquierdo,
entonces visita la raíz.
private void traversePostorder (TreeNode root) A
{ /
if (root != null) B C
{ /
traversePostorder (root.getLeft()); D E
traversePostorder (root.getRight());
process (root.getValue()); DEBCA
}
}
e
br
c tu
O
12
LUIS F. AGUAS B. 13
20
14. RECORRIDO INORDEN
Inorden: primero atraviesa el subarbol
izquierdo, entonces visita la raíz, entonces
atraviesa el subarbol derecho
A
private void traverseInorder (TreeNode root) /
{ B C
if (root != null) /
{ D E
traverseInorder (root.getLeft());
process (root.getValue());
DBEAC
traverseInorder (root.getRight());
}
br }
e
u
ct
O
12
LUIS F. AGUAS B. 14
20
16. 1 // Fig. 20.17: Tree.java
2 // Declaration of class TreeNode and class Tree.
3 package com.deitel.jhtp5.ch20;
4
5 // class TreeNode declaration
6 class TreeNode {
7
8 // package access members
9 TreeNode leftNode; Nodo izquierdo y derecho
10 int data;
11 TreeNode rightNode;
12
13 // initialize data and make this a leaf node
14 public TreeNode( int nodeData )
15 {
16 data = nodeData;
17 leftNode = rightNode = null; // node has no children
18 }
19
20 // locate insertion point and insert new node; ignore duplicate values
21 public synchronized void insert( int insertValue )
22 {
Si no se puede ingresar ir a derecho
23 // insert in left subtree
24 if ( insertValue < data ) {
25
26 // insert new TreeNode
27 if ( leftNode == null )
28 leftNode = new TreeNode( insertValue );
e
br
29
c tu
O
12
LUIS F. AGUAS B. 16
20
17. 30 else // continue traversing left subtree
31 leftNode.insert( insertValue );
32 }
33
34 // insert in right subtree
35 else if ( insertValue > data ) {
36 Si el valor es mayor
37 // insert new TreeNode
enotnces inserte al lado
38 if ( rightNode == null )
39 rightNode = new TreeNode( insertValue );
derecho
40
41 else // continue traversing right subtree
42 rightNode.insert( insertValue );
43 }
44
45 } // end method insert
46
47 } // end class TreeNode
48
49 // class Tree declaration
50 public class Tree {
51 private TreeNode root;
52
53 // construct an empty Tree of integers
54 public Tree()
55 {
56 root = null;
57 }
58 e
59 u br
// insert a new node in the binary search tree
ct
O public synchronized void insertNode( int insertValue )
60
12
LUIS F. AGUAS B. 17
61 20 {
18. 62 if ( root == null )
63 root = new TreeNode( insertValue ); // create the root node here
64
65 else
66 root.insert( insertValue ); // call the insert method
67 }
68
69 // begin preorder traversal
70 public synchronized void preorderTraversal()
71 {
72 preorderHelper( root );
73 }
74
75 // recursive method to perform preorder traversal
76 private void preorderHelper( TreeNode node )
77 {
78 if ( node == null )
79 return;
80
81 System.out.print( node.data + " " ); // output node data Recorrido en preorden
82 preorderHelper( node.leftNode ); // traverse left subtree
83 preorderHelper( node.rightNode ); // traverse right subtree
84 }
85
86 // begin inorder traversal
87 public synchronized void inorderTraversal()
88 {
89 inorderHelper( root );
90 } re
ub
91 ct
O
12
LUIS F. AGUAS B. 18
20
19. 92 // recursive method to perform inorder traversal
93 private void inorderHelper( TreeNode node )
94 {
95 if ( node == null )
96 return;
97
98 inorderHelper( node.leftNode ); // traverse left subtree
99 System.out.print( node.data + " " ); // output node data
Recorrido inorden
100 inorderHelper( node.rightNode ); // traverse right subtree
101 }
102
103 // begin postorder traversal
104 public synchronized void postorderTraversal()
105 {
106 postorderHelper( root );
107 }
108
109 // recursive method to perform postorder traversal
110 private void postorderHelper( TreeNode node )
111 {
112 if ( node == null )
113 return;
114
115 postorderHelper( node.leftNode ); // traverse left subtree
116 postorderHelper( node.rightNode ); // traverse right subtree Recorrido postorden
117 System.out.print( node.data + " " ); // output node data
118 }
119
120 } // end re
class Tree
b u
ct
O
12
LUIS F. AGUAS B. 19
20
20. 1 // Fig. 20.18: TreeTest.java
2 // This program tests class Tree.
3 import com.deitel.jhtp5.ch20.Tree;
4
5 public class TreeTest {
6
7 public static void main( String args[] )
8 {
9 Tree tree = new Tree();
10 int value;
11
12 System.out.println( "Inserting the following values: " );
13
14 // insert 10 random integers from 0-99 in tree
Insertar 10 enteros
15 for ( int i = 1; i <= 10; i++ ) {
16 value = ( int ) ( Math.random() * 100 ); en árbol
17 System.out.print( value + " " );
18 tree.insertNode( value );
19 }
20
21 System.out.println ( "nnPreorder traversal" ); Recorrido preorden
22 tree.preorderTraversal(); // perform preorder traversal of tree
23
24 System.out.println ( "nnInorder traversal" ); Recorrido inorden
25 tree.inorderTraversal(); // perform inorder traversal of tree
e
br
c tu
O
12
LUIS F. AGUAS B. 20
20
21. ÁRBOL IMPLEMENTACIÓN
26
27 System.out.println ( "nnPostorder traversal" );
Recorrido postorden
28 tree.postorderTraversal(); // perform postorder traversal of tree
29 System.out.println();
30 }
31
32 } // end class TreeTest
Inserting the following values:
39 69 94 47 50 72 55 41 97 73
Preorder traversal
39 69 47 41 50 55 94 72 73 97
Inorder traversal
39 41 47 50 55 69 72 73 94 97
Postorder traversal
41 55 50 47 73 72 97 94 69 39
e
br
c tu
O
12
LUIS F. AGUAS B. 21
20
22. ÁRBOLES BINARIOS
Árboles binarios
Estructuras de datos donde cada nodo tiene dos
sucesores, a izquierda y a derecha.
Ejemplo
Creación
Inserción
Borrado
Árbol balanceado: un árbol está balanceado cuando la
altura de la trayectoria más corta hacia una hoja no
difiere de la altura de la trayectoria más grande.
Inconveniente de los binarios: se desbalancean
fácilmente.
e
br
c tu
O
12
LUIS F. AGUAS B. 22
20
23. ÁRBOLES AVL
Árboles AVL
Árbol binario balanceado en altura (BA(1)) en el que las
inserciones y eliminaciones se efectúan con un mínimo de
accesos.
Árbol balanceado en altura:
Para cada nodo existe un límite en la diferencia que se permite entre
las alturas de cualquiera de los subárboles del nodo (BA(k)), donde k
es el nivel de balance)
Ejemplos:
e
br
c tu
O
12
LUIS F. AGUAS B. 23
20
24. ÁRBOLES CARACTERÍSTICAS
Características Árboles binarios
Estructura que debe ser respetada paginados
Mantener árbol, rotaciones
Problemas de almacenamiento
secundario, buffering, páginas
restringidas a un área local del árbol
de memoria, varios registros
Binario: profundos. Búsqueda: individuales, minimiza el número
Log2(N+1) de accesos
AVL: diferencia de 1. Búsqueda: 1.44 Problema: construcción
log2(N+2) descendente, como se elige la
(búsqueda en el peor caso) raíz?, cómo va construyendo
balanceado?
e
br
c tu
O
12
LUIS F. AGUAS B. 24
20
25. ÁRBOLES MULTICAMINO Y B
Árboles multicamino
Generalización de árboles binarios, c/nodo tiene k
punteros y k-1 claves (o registros), disminuye la
profundidad del árbol,
Orden del árbol.
Árboles B (balanceados)
Son árboles multicamino con una construcción especial en
forma ascendente que permite mantenerlo balanceado a
bajo costo.
e
br
c tu
O
12
LUIS F. AGUAS B. 25
20
26. ÁRBOLES B PROPIEDADES
Propiedades de un árbol B de orden M:
Ningún nodo tiene más de M hijos
C/nodo (menos raíz y los terminales) tienen como mínimo [M/2] hijos
La raíz tiene como mínimo 2 hijos (o sino ninguno)
Todos los nodos terminales a igual nivel
Nodos no terminales con K hijos contienen K-1 registros. Los nodos
terminales tienen:
Mínimo [M/2] –1 registros
Máximo M – 1 registros
Formato del nodo
e
br
c tu
O
12
LUIS F. AGUAS B. 26
20
27. ÁRBOLES OPERACIONES
Definición: nodo adyacente hermano
Dos nodos son adyacentes hermanos si tienen el mismo padre y son apuntados por
punteros adyacentes en el padre.
Operaciones
Búsqueda
Borrado
Creación e inserción
Modificación
e
br
c tu
O
12
LUIS F. AGUAS B. 27
20
28. ÁRBOLES: BÚSQUEDA
Búsqueda de información
Comienza desde el nodo raíz
Busca la llave en el nodo
Si no la localiza se toma el puntero anterior a la llave mayor
Si no es puntero nulo se toma ese nodi y se repite del principio. Si es un
puntero nulo el elemento no se encuentra en el árbol.
Performance
Orden M, # de nodos terminales N, N+1 punteros nulos.
Accesos:
Mejor caso: 1 lectura
Pero caso: h lecturas (con h altura del árbol)
e
br
c tu
O
12
LUIS F. AGUAS B. 28
20
29. ÁRBOLES: # LECTURAS
Como acotamos h
Nivel # mínimo de descendientes
1 2
2 2 * [M/2]
3 2 * [M/2] * [M/2]
………………………………………………….
h 2 * [M/2]h-1
Relación entre h y # de nodos
N+1 >= 2 * [M/2]h-1
h <= [ 1 + log[M/2] ((N+1)/2) ]
M = 512 y N = 1000000
h <= 3.37 (4 lecturas encuentra un registro)
e
br
c tu
O
12
LUIS F. AGUAS B. 29
20
30. ARBOLES ALGORITMOS
Algoritmo (iterativo) Algoritmo (recursivo)
encontro := false (k llave) orden M estruc. del registro
Record
tomar la raíz contador llaves
Repeat llaves (arreglo M-1 elem.)
hijos (arreglo M elem.)
N nro de elementos nodo End
Case Function Busca (Nrr, llave,NRR_encon, Pos_enc)
k = llave del registro Si Nrr = nulo
entonces devuelve (‘no encon’)
encontro := true sino lee nodo apuntado x NRR en página
k < llave( R1) busca la llave en nodo;
P := Po Pos:= Posición donde encuentra o
k > llave (Rn) debería estarla llave
Si encontro llave
P := Pn entonces
otherwise nrr_encon := Nrr (nodo con la
P := Pi (i/ Ri-1 < k <Ri) llave)
pos_enc := pos (posición dentro de
EndCase llave)
IF P not null then devuelve (encontrada)
leer nodo apuntado por P sino {busco en el nivel inferior}
Until encontro or P null devuelve (busca( hijo[pos],llave,
nrr_encon, pos_enc))
Fin S
Fin S
Fin Function
e
br
c tu
O
12
LUIS F. AGUAS B. 30
20
31. ÁRBOLES: INSERCIÓN
Inserción (creación)
Los registros se insertan en un nodo Terminal
Casos posibles
El registro tiene lugar en el nodo Terminal (no se produce overflow): solo se hacen
reacomodamientos internos en el nodo
El registro no tiene lugar en el nodo Terminal (se produce overflow): el nodo se divide y
los elementos se reparten entre los nodos, hay una promoción al nivel superior, y esta
puede propagarse y generar una nueva raíz.
e
br
c tu
O
12
LUIS F. AGUAS B. 31
20
32. ÁRBOLES: INSERCIÓN
Repeat
Algoritmo (iterativo) IF nodo no esta lleno
{ reg.: reg a insertar Then
fin: inserción finalizada poner reg y reordenar
encontro
encontro: elemento ya está Else
P: puntero al nodo copiar el nodo en N_G
N_G: nodo sobredimensionado insertar reg. en N_G
N : # reg } reg:= centro de N_G
nodo corr.:=1/2 N_G izq
{busco la llave en el árbol}
nodo nuevo:=1/2 N_G der
If encontro If nodo raiz nuevo
Then Informar llave repetida then generar nuevos
Else { insertar elemento } punteros
P := nil Until encontro
encontro := falso
e
br
c tu
O
12
LUIS F. AGUAS B. 32
20
33. ÁRBOLES: INSERCIÓN
Algoritmo (recursivo) Si valordevuelto <> promocion
Funcion inserta (Nrr_Actual, llave, entonces devuelve(valordevuelto)
hijo_promo, llave_promo) sino
Si Nrr_Actual = nulo si hay espacio en pagina para
entonces llave_p_a
llave_promo := llave entonces insertar(llave_p_a, nrr_p_a
hijo_promo := nulo en pagina) promovida abajo
devuelve Promocion (promueve llave
devuelve (no promocion)
original y nulo)
sino divide( llave_p_a, nrr_p_a,
sino
leer página de Nrr_acutal en pagina pagina, llave_promo,
buscar llave en pagina hijo_promo, página_nueva)
pos := posicion donde deberia estar escribe pagina en archivo en
en llave nrr_actual
Si encuentra llave escribe pagina_nueva en
entonces devuelve (error) hijo_promo
valordevuelto := inserta(pagina, devuelve promoción promociona
hijo[pos], llave, nrr_P_A, Fin Si llave_promo, hijo_promo
llave_P_a)
fin funcion
e
br
c tu
O
12
LUIS F. AGUAS B. 33
20
34. DIRECTORIO
Procedimiento Divide (llave_i, nrr_i, Performance
pagina, llave_promo, hijo_promo, Mejor caso (sin overflow)
pagina_nueva )
copiar pagina + llave a un nodo que H lecturas
pueda contener a todas las llaves. 1 escritura
insertar llave_i, nrr_i en los
lugares correctos de la pagina Peor caso (overflow hasta la raíz,
crear una nueva pagina para aumenta en uno el nivel del
pagina_nueva
asignar a llave_promo el valor de la
árbol)
llave de enmedio de la pagina H lecturas
grande 2h+1 escrituras (dos por nivel más
asignar a hijo_d_promo el nrr de
pagina_nueva
la raíz)
copiar las llaves y apuntadores que Estudios realizados
preceen a llave_promo en pagina M = 10 25% divisiones
idem posteriores pagina_nueva
fin procedimiento M = 100 2% divisiones
e
br
c tu
O
12
LUIS F. AGUAS B. 34
20
35. ÁRBOLES: ELIMINACIÓN
Eliminación
Mejor caso: borra un elemento del nodo y no produce
underflow, solo reacomodos ( # elementos >= [M/2]-1
Peor caso: se produce underflow, #elementos < [M/2] – 1
Eliminar
Nodo Terminal
Nodo no Terminal ( llevar a un nodo Terminal)
Dos soluciones
Redistribuir
concatenar
e
br
c tu
O
12
LUIS F. AGUAS B. 35
20
36. ÁRBOLES: REDISTRIBUIR
Redistribuir
Cuando un nodo tiene underflow puede trasladarse llaves de un nodo adyacente
hermano (en caso que este tenga suficientes elementos)
Concatenación:
Si un nodo adyacente hermano está al mínimo (no le sobra ningún elemento) no se
puede redistribuir, se concatena con un nodo adyacente disminuyendo el # de nodos (y
en algunos casos la altura del árbol)
e
br
c tu
O
12
LUIS F. AGUAS B. 36
20
37. ÁRBOLES: PERFORMANCE
Performance
Mejor caso (borra de un nodo Terminal)
H lecturas
1 escritura
Peor caso (concatenación lleva a decrementar el nivel del árbol en 1)
2h – 1 lecturas
H + 1 escrituras
e
br
c tu
O
12
LUIS F. AGUAS B. 37
20
38. ÁRBOLES: ELIMINACIÓN
Algoritmo de eliminación (iterativo) copiar ady y nodo actual en n_g
{ fin: indica fin del borrado dividir n_g
n_g:nodo tamaño mayor al normal promover nueva llave a padre
ady: nodo adyacente hermano armar nodo actual y ady con la
reg: reg. a borrar}
{buscar reg en el árbol } mitad de n_g en c/u
If reg no está en un nodo terminal fin := true
then else {concatenar}
buscar el sucesor de reg en un elegir el mejor ady para concat.
nodo terminal poner ady y nodo actual juntos y
intercalar reg con su sucesor acoplarle elemnto nodo padre
{ eliminación de reg } eliminar nodo que sobra y producir
fin := falso enganches
repeat nuevo reg elemento que bajo nodo
remover reg y el puntero asociado padra y que debemos eliminar
If nodo corriente > [M/2] -1 elem. Until fin
then fin := true IF no hay registro en la raiz
else if es posible redistribuir then
then {redistribuir}{ady.>min.} nueva raiz nodo corriente
liberar vieja raíz
e
br
c tu
O
12
LUIS F. AGUAS B. 38
20
39. CAPITULO 8
PREGUNTAS Y RESPUESTAS
e
br
c tu
O
12
LUIS F. AGUAS B. 39
20
Notes de l'éditeur
Note two constructors: one creates a node with given children, another creates a node with no children.