Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Clase 6 EDFall 2011 Arboles 1
Clase 6 EDFall 2011 Arboles 1
Clase 6 EDFall 2011 Arboles 1
Website: http://yalma.fime.uanl.mx/~romeo/ED/2011/
Sesiones: 48
Material de apoyo:
Estructura de Datos con C y C++.
Yedidyah Langsam, Moshe J. Augenstein, Aaron M. Tenenbaum, Brooklyn
College
Segunda Edición, Prentice-Hall.
Estructura de Datos.
Román Martínez, Elda Quiroga.
Thomson Learning.
Temario:
◦ Árboles en general
◦ Árboles binarios
◦ Árboles balanceados
◦ Árboles multicaminos
Árboles
EnInformática, los árboles son abstracciones matemáticas que
juegan un rol central en el diseño y análisis de algoritmos, porque:
◦ Los usamos para describir propiedades dinámicas de los algoritmos
◦ Construimos estructuras de datos que son realizaciones concretas de árboles.
El resto de los nodos se les conoce como rama, ya que tienen padre y uno
o varios hijos.
Árboles
En computación, usualmente se usa el término árbol para referirse a un
árbol con raíz. Mientras que se asume el término árbol libre para referirse
a la estructura más general.
Un árbol a partir de un nodo raíz R y k árboles A1, A2, A3,…, Ak con raíces
n1, n2, n3, …, nk respectivamente, y N1, N2, N3,…, Nk nodos cada uno.
Un recorrido es una sucesión de nodos del árbol de tal forma que entre
cada dos nodos consecutivos de la sucesión hay una relación de
parentesco.
Árboles: Definición General
Existen dos recorridos típicos para listar los nodos de un árbol: en
profundidad y en anchura.
descendiente hermanos
hoja
Árboles Binarios
Nivel de un árbol binario: La raíz del árbol tiene el nivel 0, y el nivel de
cualquier otro nodo en el árbol es uno más el nivel de su padre.
Nivel = 0
Nivel = 1
Nivel = 2
Nivel = 3
Profundidad
Null
father(p) : Retorna un info(p) : Retorna el contenido del
apuntador al padre del nodo nodo, en este ejemplo es a
p
a right(p) : Retorna un apuntador
left(p) : Retorna un apuntador
al hijo izquierdo del nodo b al hijo derecho del nodo
c
d e f g
isLeft(d) = true isLeft(e) = false isRight(g) = true
Note que si no existe un nodo que satisfaga cualquiera de las funciones anteriores, se
retorna un nulo (null) entonces.
return false;
d e f g
if(left(q) == p)
return true;
Implementa isRight(p)!
return false;
Árboles Binarios: Operaciones
brother(p) father
a
if(father(p) == null)
b c brother(c) ?
return null;
if(isLeft(p)) d e f g
return right(father(p))
return left(father(p))
Operaciones adicionales:
-makeTree(p) : Crea un árbol binario con un nodo único (raíz)
- setLeft(p, x) : Establece un nodo x como hijo izquierdo de otro nodo p,
siempre y cuando p no tenga un hijo del lado izquierdo ya establecido.
- setRight(p, x) : Similar a la función anterior.
Árboles Binarios: Aplicación de Ejemplo
Los árboles binarios son útiles cuando se toman decisiones en dos sentidos
en cada punto del proceso.
Ejemplo: Encontrar todos los duplicados en una lista de números: {15,4,8,
7, 4, 3, 19, 5, 7, 9, 16, 5,17}
Algoritmo: Primer elemento es la raíz, subsecuentes elementos se colocan
a la izquierda si son menores o a la derecha si son mayores. Si son
duplicados no se insertan pero se reportan.
15 15 15 15 15
4 4 4 4 4
8 8
3 8
7 7
Árboles Binarios: Aplicación de Ejemplo
{15,4,8, 7, 4, 3, 19, 5, 7, 9, 16, 5,17}
15 15 15
4 19 4 19 4 19
3 8 3 8 3 8 16
7 7 7 9 17
…
5 5
Árboles Binarios: Aplicación de Ejemplo
Pseudocódigo:
15
int numbers[13] = {15,4,8, 7, 4, 3, 19, 5, 7, 9, 16,
5,17};
tree = makeTree(numbers[0]);
4 19
for(int i=1;i<length(numbers);i++){
p = q = tree;
while(numbers[i] !=info(p) && q!=NULL){
3 8 16
p = q;
if(numbers[i]<info(p))
q = left(p); 7 9 17
else
q = right(p);
} 5
if(numbers[i] == info(p))
cout<<“Numero repetido”;
else if(numbers[i] < info(p))
setleft(p,numbers[i]);
else
setright(p, numbers[i]);
Ejemplo 2: Expresiones
La raíz del árbol binario contiene un operador que se aplicará a la
evaluación de las expresiones representadas por sus subárboles
izquierdo y derecho.
Los operandos son únicamente hojas en el árbol
+
$
A *
+ *
A+B*C B C
A * + C
B C A B
+ C
(A+B*C)$((A+B)*C)
A B (A+B)*C
Representación básica de un árbol binario
struct tnode {
int info;
struct tnode * father; //No necesario
struct tnode * left;
Info L F R
struct tnode * right;
};
p
typedef struct tnode * TNODEPTR;
TNODEPTR createNode() {
TNODEPTR p = (TNODEPTR)
malloc(sizeof(struct tnode));
return p;
}
void freeNode(TNODEPTR P) {
free( p);
}
Representación básica de un árbol binario
TNODEPTR makeTree(int x) {
TNODEPTR root = createNode();
root->info = x;
root->father = NULL;
root->left = NULL; X NULL NULL NULL
root->right = NULL;
return root;
}
TNODEPTR father(TNODEPTR pNode) {
return pNode->father;
}
makeTree(x);
X N N N X N N
pNode->left=…
father
a
b c sibling(c) ?
d e f g
Árbol binario de búsqueda u ordenado
El ejemplo anterior introdujo el árbol binario de búsqueda o
árbol binario ordenado
4 19
//Dado un árbol binario, inserta un
//nuevo nodo en el lugar correcto del arbol.
TNODEPTR insert(TNODEPTR pNode, int data){ 3 8 16
//1: Si el arbol esta vacio retorna
//un nodo unico
if(pNode==NULL){
return makeTree(data); 1 7 9 17
} else{
//Recursa hacia abajo del arbol
//Para encontrar el lugar correcto 5
if(data<=pNode->info){
pNode->left = insert(pNode->left, data);
}else{
pNode->right = insert(pNode->right, data);
}
//Retorna el nodo original sin cambiar
return(pNode);
}
}
Árbol binarios: Ejercicio simple
Escribe código que implemente el siguiente árbol binario:
a) Llamando a makeTree tres veces
2 y usando tres variables puntero.
TNODEPTR build123(){
TNODEPTR one, two three;
one = makeTree(1);
1 3
two = makeTree(2);
three = makeTree(3);
two->left = one;
two->right = three;
b) Llamando a makeTree tres veces return two
}
y usando una variable puntero.
3 D 6 E F 9
ABDGCEHIF
4 G H I
7 8
Recorrido de árboles binarios
Orden Simétrico/Inorden:
1. Recorrer el subárbol izquierdo en orden simétrico
2. Recorrer la raíz
3. Recorrer el subárbol derecho en orden simétrico
1 D 6 E F 9
DGBAHEICF
2 G H I
5 7
Recorrido de árboles binarios
Orden Posterior:
1. Recorrer el subárbol izquierdo en orden posterior
2. Recorrer el subárbol derecho en orden posterior
3. Recorrer la raíz
2 D 6 E F 7
GDBHIEFCA
1 G H I
4 5
Remoción en un árbol binario ordenado
15
15 15
15
3
3 8
8 16
16 88 16
16
15
15 15
15
4
4 19
19 88 19
19
◦ Si el nodo a suprimir sólo tiene un subárbol: Su
único hijo se mueve hacia arriba y ocupa su lugar
8
8 16
16 16
16
15
15
44 23
19
23
19
else { 44 23
19
23
19
TNODEPTR f = p;
rp = p-> right; 3
3 88 16
16 25
25
TNODEPTR s = rp->left;
while (s != NULL) { 18 23
24
18 23
24
f = rp;
rp = s; 24
24
Árboles Balanceados
Laaltura (profundidad) de un árbol binario es el nivel
máximo de sus hojas
00
1
1
0 1 -1
-1
0 0 1
0
0 00 00
0
0 0
0 0
0 0
00 00
0
0 0
0
Por ejemplo:
P = {data=10, left=7, right=15, FE=2}
p
10
10
7
7 15
15
5
5 8
8
2
2 6
6
Árbol AVL: Rotaciones
7
7
5
5 10
10
2,5,6,7,8,10,15
2
2 6
6 8
8 15
15
10
10
5
5
77 15
15
2
2 7
7
55 88
6
6 10
10
2,5,6,7,8,10,15
Recorrido Inorder
8
8 15
15 22 66
l r l lr’
5
5 10
10 55 88
lr’ r’
2
2 6
6 8
8 15
15
22 66
Rotación izquierda
p r’
Si la inserción se produce en el hijo derecho (lr’) del 77 15
15
12
12
Rotación a Rotación a
la izquierda la derecha 99
9
9 15
15
7
7 12
12
7
7 10
10
5
5 88 10
10 15
15
5
5 8
8
2
2 6
6
2
2 6
6
Casos de Inserción
La inserción funciona como si fuera un árbol de búsqueda
binario desequilibrado, retrocediendo hacia la raíz y rotando
sobre cualquier nodo no balanceado.
Nuevo nodo
Nuevo nodo
Solución: Rotación Izquierda
X X X
B C D E
6 10 60 70 80 100 120 150
37
F G H
25 62 65 69 110
Árboles Multicaminos: Operaciones Básicas
numTrees(p): Dado un nodo multicamino p, retorna el número de hijos
(subárboles) de p (0<=numTrees(p)<=n). Donde n es el orden o grado del árbol.
child(p,i): Retorna el i_ésimo hijo del nodo p. Donde 0<=i<numTrees(p)-1.
key(p,j): Retorna la j_ésima llave del nodo p. Donde 0<=j<numTrees(p)-2 son las
llaves en orden ascendente
numTrees(A) => 4
A key(A,2)
key(A,0)
12 50 85
child(A,0) child(A,3)
B C D E
B C D E
60 70 80 100 120 150
6 10 37
traverse(T node){
if(node != NULL){
nt = 4
nt = numTrees(node);
0<=i<3
for(i = 0; i<nt-1; i++){
traverse(son(node,i)); key(A,0), Key(A,1), Key(A,2)
A
cout<<key(node, i);
} 12 50 85
traverse(son(node,nt-1));
} son(A,0) son(A,1) son(A,2) son(A,3)
} B C D E
60 70 80 100 120 150
6 10 37
Árboles Multicaminos: Operaciones Básicas
Acceso secuencial directo: Accede a la siguiente llave partiendo de
otra que se le conoce su posición en el árbol. Asumimos que la llave
que conocemos se encuentra en Key(node, index)