Professional Documents
Culture Documents
Un rbol es una coleccin de elementos de un tipo determinado, cada uno de los cuales se almacena en un nodo. Existe una relacin de paternidad entre los nodos que determina una estructura jerrquica sobre los mismos. A
Estructuras de Datos II
Tema 1 rboles
D G
N P
R I
T H
Una definicin recursiva ms formal es la siguiente: Un solo nodo es, por s mismo, un rbol. Este nico nodo se llama nodo raz del rbol.
Definiciones
Grado: Nmero de hijos de un nodo. El grado de un rbol es el mximo de los grados de sus nodos. A 4 F 0 L 1 K 3 0 E R 0 0 I B 2 J 0 0D 3 G 1 S 3 2 Q 0 P 0 O 0
Si n es un nodo y A1, A2, ..., Ak son rboles con races n1, n2, ..., nk, respectivamente, y se define una relacin padre-hijo entre n y n1, n2, ..., nk, entonces la estructura resultante es un rbol. En este rbol, n es la raz, A1, A2, ..., Ak son subrboles de la raz, n es el padre de los nodos n1, n2, ..., nk y stos, por tanto, son los hijos de n y hermanos entre s. n
n1
n2
nk
0 M
C 0
A1
A2
Ak
H 0
3 4
Adems, llamaremos rbol nulo o rbol vaco a aqul que no tiene ningn nodo.
Camino: Una sucesin de nodos de un rbol n1, n2, ..., nk, tal que ni es el padre de ni+1 para 1 i k. La longitud de un camino es el nmero de nodos menos 1. Por tanto, existe un camino de longitud 0 de cualquier nodo a s mismo.
Ancestros y descendientes: Si existe un camino de un nodo a a otro b, entonces a es un antecesor o ancestro de b y b es un descendiente de a. Un ancestro o descendiente de un nodo distinto de s mismo se llama ancestro propio o descendiente propio, respectivamente.
D G
N P
D G
N P
R I
R I
T H
T H
Raz: nico nodo de un rbol que no tiene antecesores propios. Hoja: Nodo que no tiene descendientes propios. Subrbol: Conjunto de nodos formado por un nodo y todos sus descendientes. Rama: Camino que termina en un nodo hoja. A
Altura: La altura de un nodo es la longitud de la rama ms larga que parte de dicho nodo. La altura de un rbol es la altura del nodo raz. Profundidad: La profundidad de un nodo es la longitud del nico camino desde la raz a ese nodo. 5 A 0 0 F 1 2 L 1 1 K 2 0 M 30 C 30 R 3 1 B 1 4 S 1
D G
N P
0 E 2 0 J 2 0D 2 3N2 0Q2 2G 3 0P 3 0 I 41 T 40 O 4 0 H 5
R I
T H
Nivel: El nivel de un nodo coincide con su profundidad. Los nodos de un rbol de altura h se clasifican en h + 1 niveles numerados de 0 a h, de tal forma que el nivel i lo forman todos los nodos de profundidad i.
nivel 0 F L
nivel 1
nivel 2 M
D G
N P
Q g
f b a i k c e l d
R I
h T H
9
10
Ai
Ad
Ai
Ad
11
12
e c l c l
13
14
i c
e l
k c
e l
15
16
a i k c e l j i
a k c e l
17
18
a j i k c e
d
j i
a k c e
19
20
b h j i a k c e l d j h
g a i k
b d e c l
21
22
f g h j i a k c e l b d
23
24
f g g a
25
26
f g a b
g a
f b d
27
28
f g h a b d j h g a
f b d
29
30
f g h j i a b d
j h i g a k
f b d
31
32
f g h j i a k e b d j h i g a k
f b d e l
33
34
f g h j i a k c e l b d
j h i g a k
f b d e c l
Abin CrearAbin () Abin CrearRaizB (tElemento e, Abin A) void InsertarHijoIzqdoB (nodo n, tElemento e, Abin A) void InsertarHijoDrchoB (nodo n, tElemento e, Abin A)
35 36
Especificacin de operaciones:
Abin CrearABin ()
Post: Crea y devuelve un rbol vaco.
37
38
39
40
f g h j i a k c
0 1 2 3 4 5 6 7 8 9 10 11 12 13
f b d e l
maxNodos 0 1 2 3 4 5 6 7 8
g h j i a k
b d e c
9 10 11 12 13
l
maxNodos
elto f g a b d h j i k e l c padre * 0 1 0 3 1 5 2 2 4 9 9
f * 1 3
g 0 5 2
a 1 7 8
b 0 * 4
d 3 9 *
h 1 6 *
j 5 * *
i 2 * *
k e l c 2 4 9 9 * 11 * * * 10 * *
42
f
g
9 10 11 12 13
maxNodos
9 10 11 12 13
maxNodos
f * * *
43
f * 1 *
g 0 * *
44
f g a g a
f b
9 10 11 12 13
maxNodos
9 10 11 12 13
maxNodos
f * 1 *
g 0 * 2
a 1 * *
45
f * 1 3
g 0 * 2
a 1 * *
b 0 * *
46
f g a x b
h x g a
f b
9 10 11 12 13
maxNodos
9 10 11 12 13
maxNodos
f * 1 3
g 0 * 2
a 1 4 *
b 0 * *
x 2 * *
47
f * 1 3
g 0 5 2
a 1 4 *
b 0 * *
x 2 * *
h 1 * *
48
f g h a b h g a
f b d
9 10 11 12 13
maxNodos
9 10 11 12 13
maxNodos
f * 1 3
g 0 5 2
a 1 * *
b 0 * *
h 1 * *
49
f * 1 3
g 0 5 2
a 1 * *
b 0 * 4
d 3 * *
h 1 * *
50
f g h y a b d
h y i g a
f b d
9 10 11 12 13
maxNodos
9 10 11 12 13
maxNodos
f * 1 3
g 0 5 2
a 1 * *
b 0 * 4
d 3 * *
h 1 * 6
y 5 * *
51
f * 1 3
g 0 5 2
a 1 7 *
b 0 * 4
d 3 * *
h 1 * 6
y 5 * *
i 2 * *
52
f g h y i a k b d h y i g a k
f b d e
9 10 11 12 13
maxNodos
9 10 11 12 13
maxNodos
f * 1 3
g 0 5 2
a 1 7 8
b 0 * 4
d 3 * *
h 1 * 6
y 5 * *
i 2 * *
k 2 * *
53
f * 1 3
g 0 5 2
a 1 7 8
b 0 * 4
d 3 9 *
h 1 * 6
y 5 * *
i 2 * *
k e 2 4 * * * *
54
f g h y i a k z e b d
h y i g a k
f b z e c d
9 10 11 12 13
maxNodos
9 10 11 12 13
maxNodos
f * 1 3
g 0 5 2
a b d h y 1 0 3 1 5 7 10 9 * * 8 4 * 6 *
i 2 * *
k e z 2 4 3 * * * * * *
55
f * 1 3
g 0 5 2
a b d h y 1 0 3 1 5 7 10 9 * * 8 4 * 6 *
i 2 * *
k e z c 2 4 3 9 * 11 * * * * * *
56
f g h y i a k c
0 1 2 3 4 5 6 7 8 9 10 11 12 13 maxNodos 0 1 2 3 4 5 6 7
f b d e h i g a k c
8 9 10 11 12 13 maxNodos
b d e
f * 1 3
g 0 5 2
a 1 7 8
b 0 * 4
d 3 9 *
h 1 * 6
y 5 * *
i 2 * *
k e 2 4 * 11 * *
c 9 * *
57
f * 1 3
g 0 5 2
a 1 7 8
b 0 * 4
d 3 9 *
h 1 * *
i 2 * *
k e 2 4 * 11 * *
c 9 * *
58
f g h j i a k c
0 1 2 3 4 5 6 7 8 9 10 11 12 13 maxNodos 0 1 2 3 4 5 6 7
b d e
j h
g a i k
b d e c
8 9 10 11 12 13
l
maxNodos
f * 1 3
g 0 5 2
a 1 7 8
b 0 * 4
d 3 9 *
h 1 6 *
j 5 * *
i 2 * *
k e 2 4 * 11 * *
c 9 * *
59
f * 1 3
g 0 5 2
a 1 7 8
b 0 * 4
d 3 9 *
h 1 6 *
j 5 * *
i 2 * *
k e l c 2 4 9 9 * 11 * * * 10 * *
60
f g h y i a k c
0 1 2 3 4 5 6 7 8 9 10 11 12 13 maxNodos 0 1 2 3 4 5 6 7
f b z e d h y i g a k c
8 9 10 11 12 13 maxNodos
b d e
f * 1 3
g 0 5 2
a b d h y 1 0 3 1 5 7 10 9 * * 8 4 * 6 *
i 2 * *
k e z c 2 4 3 9 * 11 * * * * * *
61
f 0 1 3
g 0 5 2
a 1 7 8
b 0 * 4
d 3 9 *
h 1 * 6
y 5 * *
i 2 * *
k e z c 2 4 * 9 * * * 11 * * * * * *
62
f g h i a k c
0 1 2 3 4 5 6 7 8 9 10 11 12 13 maxNodos 0 1 2 3 4 5 6 7
b d e
j h
g a i k
b d e c
8 9 10 11 12 13 maxNodos
f 0 1 3
g 0 5 2
a 1 7 8
b 0 * 4
d 3 9 *
h 1 * *
y * * *
i 2 * *
k e z c 2 4 * 9 * * * 11 * * * * * *
f 0 1 3
g 0 5 2
a 1 7 8
b 0 * 4
d 3 9 *
h 1 6 *
j 5 * *
i 2 * *
k e z c 2 4 * 9 * * * 11 * * * * * *
64
f g h j i a k c
0 1 2 3 4 5 6 7 8 9 10 11 12 13
f b d e l numNodos 1
maxNodos 0 1 2 3 4 5 6 7 8 9 10 11 12 13 maxNodos
f 0 1 3
g 0 5 2
a 1 7 8
b 0 * 4
d 3 9 *
h 1 6 *
j 5 * *
i 2 * *
k e l c 2 4 9 9 * * * 11 * * * 10 * *
f * * *
66
f g
g a
numNodos 2
0 1 2 3 4 5 6 7 8 9 10 11 12 13 maxNodos
numNodos 3
0 1 2 3 4 5 6 7 8 9 10 11 12 13 maxNodos
f * 1 *
g 0 * *
67
f * 1 *
g 0 * 2
a 1 * *
68
f g a x b g a
f b
numNodos 4
0 1 2 3 4 5 6 7 8 9 10 11 12 13 maxNodos
numNodos 5
0 1 2 3 4 5 6 7 8 9 10 11 12 13 maxNodos
f * 1 3
g 0 * 2
a 1 * *
b 0 * *
69
f * 1 3
g 0 * 2
a 1 4 *
b 0 * *
x 2 * *
70
f g h x a b
h g a
f b
numNodos 6
0 1 2 3 4 5 6 7 8 9 10 11 12 13 maxNodos
numNodos 5
0 1 2 3 4 5 6 7 8 9 10 11 12 13 maxNodos
f * 1 3
g 0 5 2
a 1 4 *
b 0 * *
x 2 * *
h 1 * *
71
f * 1 3
g 0 4 2
a 1 * *
b 0 * *
h 1 * *
h 1 * *
72
f g h a b d h y g a
f b d
numNodos 6
0 1 2 3 4 5 6 7 8 9 10 11 12 13 maxNodos
numNodos 7
0 1 2 3 4 5 6 7 8 9 10 11 12 13 maxNodos
f * 1 3
g 0 4 2
a 1 * *
b 0 * 5
h 1 * *
d 3 * *
73
f * 1 3
g 0 4 2
a 1 * *
b 0 * 5
h 1 * 6
d 3 * *
y 4 * *
74
f g h w y a b d
w h y g a z
f b d
numNodos 8
0 1 2 3 4 5 6 7 8 9 10 11 12 13 maxNodos
numNodos 9
0 1 2 3 4 5 6 7 8 9 10 11 12 13 maxNodos
f * 1 3
g 0 4 2
a 1 * *
b 0 * 5
h 1 7 6
d 3 * *
y 4 * *
w 4 * *
75
f * 1 3
g 0 4 2
a 1 * 8
b 0 * 5
h 1 7 6
d 3 * *
y 4 * *
w 4 * *
z 2 * *
76
f g h w y a z e b d w h y g a z
f b d e c
10 0 1 2 3 4 5 6 7 8 9 10 11 12 13 maxNodos
numNodos g 0 4 2 a 1 * 8 b 0 * 5 h 1 7 6 d 3 9 * y 4 * * w 4 * * z e 2 5 * * * *
77
11 0 1 2 3 4 5 6 7 8 9 10 11 12 13 maxNodos
f * 1 3
f * 1 3
g 0 4 2
a 1 * 8
b 0 * 5
h 1 7 6
d 3 9 *
y 4 * *
w 4 * *
z e c 2 5 9 * 10 * * * *
78
b d e l
numNodos
11 0 1 2 3
g h y a z
b d e c l
maxNodos
9 10 11 12 13
f * 1 3
g 0 4 2
a 1 * 8
b 0 * 5
h 1 7 6
d 3 9 *
y 4 * *
w 4 * *
z e c l 2 5 9 9 * 10 * * * 11 * *
79
f * 1 3
g 0 4 2
a 1 * 8
b 0 * 5
h 1 * 6
d 3 9 *
y 4 * *
l 9 * *
z e c l 2 5 9 9 * 10 * * * 7 * *
80
f b g d e l numNodos 9
0 1 2 3 4 5 6 7 8 9 10 11 12 13 maxNodos
b a e c l d
f * 1 3
g 0 4 2
a 1 * *
b 0 * 5
h 1 * 6
d 3 9 *
y 4 * *
l 9 * *
c 9 * *
e 5 8 7
c 9 * *
l 9 * *
81
f * 1 3
g 0 4 2
a 1 * *
b 0 * 5
h 1 * *
d 3 6 *
e 5 8 7
l 6 * *
c 6 * *
e 5 8 7
c 9 * *
l 9 * *
82
b d e l
numNodos
11 0 1 2 3
g h i a k
b d e c l
maxNodos
9 10 11 12 13
f * 1 3
g 0 4 2
a 1 * 9
b 0 * 5
h 1 * *
d 3 6 *
e 5 8 7
l 6 * *
c 6 * *
k 2 * *
c 9 * *
l 9 * *
83
f * 1 3
g a b h d 0 1 0 1 3 4 10 * * 6 2 9 5 * *
e 5 8 7
l 6 * *
c 6 * *
k 2 * *
i 2 * *
l 9 * *
84
/* Por ejemplo */
b d e l
f * 1 3
g a b h 0 1 0 1 4 10 * 11 2 9 5 *
d 3 6 *
e 5 8 7
l 6 * *
c 6 * *
k 2 * *
i 2 * *
j 4 * *
85
#ifndef _ARBOL_BINARIO_ #define _ARBOL_BINARIO_ typedef int nodo; /* ndice de la matriz entre 0 y maxNodos-1 */ struct celda { tElemento elto; nodo padre, hizq, hder; }; typedef struct tArbol { struct celda *nodos; int maxNodos; int numNodos; } tipoArbol; typedef tipoArbol *Abin;
86
Abin CrearAbin (int maxNodos); void CrearRaizB (tElemento e, Abin A); void InsertarHijoIzqdoB (nodo n, tElemento e, Abin A); void InsertarHijoDrchoB (nodo n, tElemento e, Abin A); void EliminarHijoIzqdoB (nodo n, Abin A); void EliminarHijoDrchoB (nodo n, Abin A); void EliminarRaizB (Abin A); void DestruirAbin (Abin A); int ArbolVacioB (Abin A); tElemento RecuperarB (nodo n, Abin A); void ModificarB (nodo n, tElemento e, Abin A); nodo RaizB (Abin A); nodo PadreB (nodo n, Abin A); nodo HijoIzqdoB (nodo n, Abin A); nodo HijoDrchoB (nodo n, Abin A); #endif
/*------------------------------------*/ /* AbinMat0.c */ /*------------------------------------*/ #include <stdlib.h> #include "error.h" #include "abinmat0.h" Abin CrearAbin (int maxNodos) { Abin A; A = (Abin) malloc(sizeof(tipoArbol)); if (!A) ERROR("CrearAbin(): No hay memoria"); A->nodos = (struct celda *)calloc(maxNodos, sizeof(struct celda)); if (!A->nodos) ERROR("CrearAbin(): No hay memoria"); A->maxNodos = maxNodos; A->numNodos = 0; return A; }
87 88
void CrearRaizB (tElemento e, Abin A) { if (A->numNodos) ERROR("CrearRaizB(): rbol no vaco"); A->numNodos = 1; A->nodos[0].elto = e; A->nodos[0].padre = NODO_NULO; A->nodos[0].hizq = NODO_NULO; A->nodos[0].hder = NODO_NULO; }
void InsertarHijoIzqdoB (nodo n, tElemento e, Abin A) { nodo hizqdo; if (n < 0 || n > A->numNodos - 1) ERROR("InsertarHijoIzqdoB(): Nodo inexistente"); if (A->nodos[n].hizq != NODO_NULO) ERROR("InsertarHijoIzqdoB(): Ya existe hijo izquierdo"); if (A->numNodos == A->maxNodos) ERROR("InsertarHijoIzqdoB(): Espacio insuficiente para hijo izqdo"); /* Aadir el nuevo nodo al final de la secuencia */ hizqdo = A->numNodos; A->numNodos++; A->nodos[n].hizq = hizqdo; A->nodos[hizqdo].elto = e; A->nodos[hizqdo].padre = n; A->nodos[hizqdo].hizq = NODO_NULO; A->nodos[hizqdo].hder = NODO_NULO; }
89 90
void InsertarHijoDrchoB (nodo n, tElemento e, Abin A) { nodo hdrcho; if (n < 0 || n > A->numNodos - 1) ERROR(...: Nodo inexistente"); if (A->nodos[n].hder != NODO_NULO) ERROR(...: Ya existe hijo derecho"); if (A->numNodos == A->maxNodos) ERROR(...: Espacio insuficiente ..."); /* Aadir el nuevo nodo al final de la secuencia */ hdrcho = A->numNodos; A->numNodos++; A->nodos[n].hder = hdrcho; A->nodos[hdrcho].elto = e; A->nodos[hdrcho].padre = n; A->nodos[hdrcho].hizq = NODO_NULO; A->nodos[hdrcho].hder = NODO_NULO; }
91
void EliminarHijoIzqdoB (nodo n, Abin A) { nodo hizqdo; if (n < 0 || n > A->numNodos - 1) ERROR(...: Nodo inexistente"); hizqdo = A->nodos[n].hizq; if (hizqdo == NODO_NULO) ERROR(... : No existe hijo izqdo."); if (A->nodos[hizqdo].hizq != NODO_NULO || A->nodos[hizqdo].hder != NODO_NULO) ERROR(...: Hijo izqdo no es hoja");
92
if (hizqdo != A->numNodos-1) { A->nodos[hizqdo]=A->nodos[A->numNodos-1]; if (A->nodos[A->nodos[hizqdo].padre].hizq == A->numNodos-1) /* El nodo movido es hijo izq. de su padre */ A->nodos[A->nodos[hizqdo].padre].hizq=hizqdo; else /* El nodo movido es hijo der. de su padre */ A->nodos[A->nodos[hizqdo].padre].hder=hizqdo; if (A->nodos[hizqdo].hizq != NODO_NULO) /* El nodo movido tiene hijo izq. */ A->nodos[A->nodos[hizqdo].hizq].padre=hizqdo; if (A->nodos[hizqdo].hder != NODO_NULO) /* El nodo movido tiene hijo der. */ A->nodos[A->nodos[hizqdo].hder].padre=hizqdo; } A->numNodos--; A->nodos[n].hizq = NODO_NULO; }
93
void EliminarHijoDrchoB (nodo n, Abin A) { nodo hdrcho; /* Comprobar precondiciones */ ... if (hdrcho != A->numNodos-1) { A->nodos[hdrcho] = A->nodos[A->numNodos-1]; if (A->nodos[A->nodos[hdrcho].padre].hizq == A->numNodos-1) A->nodos[A->nodos[hdrcho].padre].hizq=hdrcho; else A->nodos[A->nodos[hdrcho].padre].hder=hdrcho; if (A->nodos[hdrcho].hizq != NODO_NULO) A->nodos[A->nodos[hdrcho].hizq].padre=hdrcho; if (A->nodos[hdrcho].hder != NODO_NULO) A->nodos[A->nodos[hdrcho].hder].padre=hdrcho; } A->numNodos--; A->nodos[n].hder = NODO_NULO; }
94
void EliminarRaizB (Abin A) { if (!A->numNodos) ERROR("EliminarRaizB(): rbol vaco"); if (A->nodos[0].hizq != NODO_NULO || A->nodos[0].hder != NODO_NULO) ERROR("EliminarRaizB(): La raz no es un nodo hoja"); A->numNodos = 0; } void DestruirAbin (Abin A) { free(A->nodos); free(A); }
int ArbolVacioB (Abin A) { return (A->numNodos == 0); } tElemento RecuperarB (nodo n, Abin A) { if (n < 0 || n > A->numNodos - 1) ERROR("RecuperarB(): Nodo inexistente"); return A->nodos[n].elto; } void ModificarB (nodo n, tElemento e, Abin A) { if (n < 0 || n > A->numNodos - 1) ERROR("ModificarB(): Nodo inexistente"); A->nodos[n].elto = e; /* Se asume que el operador = es compatible con tElemento. Si no es as, hay que implementar una funcin privada para la realizar la copia. */ }
95 96
nodo RaizB (Abin A) { if (A->numNodos) return 0; else return NODO_NULO; } nodo PadreB (nodo n, Abin A) { if (n < 0 || n > A->numNodos - 1) ERROR("Padre(): Nodo inexistente"); return A->nodos[n].padre; }
nodo HijoIzqdoB (nodo n, Abin A) { if (n < 0 || n > A->numNodos - 1) ERROR("HijoIzqdo(): Nodo inexistente"); return A->nodos[n].hizq; } nodo HijoDrchoB (nodo n, Abin A) { if (n < 0 || n > A->numNodos - 1) ERROR("HijoDrcho(): Nodo inexistente"); return A->nodos[n].hder; }
97
98
g h i a k
b d e c l
maxNodos-1 25 26 27 28 29 30 0 1 2 3 4 5 6 7 8
b d e l
maxNodos-1 9 10 11 12 13 14 15 25 26 27 28 29 30
nodos f g b h a
d j
i k
c l
nodos f
99
100
b a n k w
7 8
g d h m l x
maxNodos-1
b a n k w
7 8
d v e u c
maxNodos-1 25 26 27 28 29 30
x n
2
i q r
5 6
p s z a y
v u c
j z
0 1
x n
2
i q r
5 6
p s z a y
t
3 4
t
3 4
9 10 11 12 13 14 15
25 26 27 28 29 30
9 10 11 12 13 14 15
nodos f g b h a n d j x i k p v e m z
y u c l x
nodos f g b h a n d j x i k p v e m z
y u c
101
102
/*-------------------------------------------*/ /* AbinMat1.h */ /*-------------------------------------------*/ #define NODO_NULO -1 typedef char tElemento; /* Por ejemplo */
b d e l
maxNodos-1 25 26 27 28 29 30
nodos f g b h a @ d j @ i k @ @ e @ @
@@ c l @@
#ifndef _ARBOL_BINARIO_ #define _ARBOL_BINARIO_ typedef int nodo; /* ndice de la matriz entre 0 y maxNodos-1 */ typedef struct tArbol { tElemento *nodos; int maxNodos; } tipoArbol; typedef tipoArbol *Abin;
103
104
Abin CrearAbin (int maxNodos); void CrearRaizB (tElemento e, Abin A); void InsertarHijoIzqdoB (nodo n, tElemento e, Abin A); void InsertarHijoDrchoB (nodo n, tElemento e, Abin A); void EliminarHijoIzqdoB (nodo n, Abin A); void EliminarHijoDrchoB (nodo n, Abin A); void EliminarRaizB (Abin A); void DestruirAbin (Abin A); int ArbolVacioB (Abin A); tElemento RecuperarB (nodo n, Abin A); void ModificarB (nodo n, tElemento e, Abin A); nodo RaizB (Abin A); nodo PadreB (nodo n, Abin A); nodo HijoIzqdoB (nodo n, Abin A); nodo HijoDrchoB (nodo n, Abin A); #endif
/*------------------------------------*/ /* AbinMat1.c */ /*------------------------------------*/ #include <stdlib.h> #include "error.h" #include "abinmat1.h #define ELTO_NULO '\0'/* Un valor "ilegal" */ Abin CrearAbin (int maxNodos) { Abin A; nodo i; A = (Abin) malloc(sizeof(tipoArbol)); if (!A) ERROR("CrearAbin(): No hay memoria"); A->nodos = (tElemento *) calloc(maxNodos, sizeof(tElemento)); if (!A->nodos) ERROR("CrearAbin(): No hay memoria"); A->maxNodos = maxNodos; for (i = 0; i < maxNodos; i++) A->nodos[i] = ELTO_NULO; return A;
105
106
void CrearRaizB (tElemento e, Abin A) { if (A->nodos[0] != ELTO_NULO) ERROR("CrearRaizB(): Arbol no vaco"); A->nodos[0] = e; } void InsertarHijoIzqdoB (nodo n, tElemento e, Abin A) { if (n < 0 || n > A->maxNodos - 1) ERROR(InsertarHijoIzqdoB(): Nodo inexistente"); if (A->nodos[n] == ELTO_NULO) ERROR(InsertarHijoIzqdoB(): Nodo inexistente"); if (A->maxNodos - 1 < 2 * n + 1) ERROR(InsertarHijoIzqdoB(): Espacio insuficiente " "para aadir hijo izquierdo"); if (A->nodos[2*n+1] != ELTO_NULO) ERROR(InsertarHijoIzqdoB(): Ya existe hijo izquierdo"); A->nodos[2*n+1] = e; }
107
void InsertarHijoDrchoB (nodo n, tElemento e, Abin A) { if (n < 0 || n > A->maxNodos - 1) ERROR(...: Nodo inexistente"); if (A->nodos[n] == ELTO_NULO) ERROR(...: Nodo inexistente"); if (A->maxNodos - 1 < 2 * n + 2) ERROR(...: Espacio insuficiente " "para aadir hijo derecho"); if (A->nodos[2*n+2] != ELTO_NULO) ERROR(...: Ya existe hijo derecho"); A->nodos[2*n+2] = e; }
108
void EliminarHijoIzqdoB (nodo n, Abin A) { nodo hizqdo; if (n < 0 || n > A->maxNodos - 1) ERROR("EliminarHijoIzqdoB(): Nodo inexistente"); if (A->nodos[n] == ELTO_NULO) ERROR("EliminarHijoIzqdoB(): Nodo inexistente"); hizqdo = 2 * n + 1; if (hizqdo > A->maxNodos - 1) ERROR("EliminarHijoIzqdoB(): No existe hijo izquierdo"); if (A->nodos[hizqdo] == ELTO_NULO) ERROR("EliminarHijoIzqdoB(): No existe hijo izquierdo"); if (A->maxNodos > 2*hizqdo+1 && A->nodos[2*hizqdo+1]!=ELTO_NULO || A->maxNodos > 2*hizqdo+2 && A->nodos[2*hizqdo+2]!=ELTO_NULO) ERROR("EliminarHijoIzqdoB(): Hijo izquierdo no es hoja"); A->nodos[hizqdo] = ELTO_NULO; }
void EliminarHijoDrchoB (nodo n, Abin A) { nodo hdrcho; if (n < 0 || n > A->maxNodos - 1) ERROR("EliminarHijoDrchoB(): Nodo inexistente"); if (A->nodos[n] == ELTO_NULO) ERROR("EliminarHijoDrchoB(): Nodo inexistente"); hdrcho = 2 * n + 2; if (hdrcho > A->maxNodos -1) ERROR("EliminarHijoDrchoB(): No existe hijo derecho"); if (A->nodos[hdrcho] == ELTO_NULO) ERROR("EliminarHijoDrchoB(): No existe hijo derecho"); if (A->maxNodos > 2*hdrcho+1 && A->nodos[2*hdrcho+1]!=ELTO_NULO || A->maxNodos > 2*hdrcho+2 && A->nodos[2*hdrcho+2]!=ELTO_NULO) ERROR("EliminarHijoDrchoB(): Hijo derecho no es hoja"); A->nodos[hdrcho] = ELTO_NULO; }
109
110
void EliminarRaizB (Abin A) { if (A->nodos[0] == ELTO_NULO) ERROR("EliminarRaizB(): rbol vaco"); if ((A->maxNodos > 1) && (A->nodos[1] != ELTO_NULO || A->nodos[2] != ELTO_NULO)) ERROR("EliminarRaizB(): La raz no es hoja"); A->nodos[0] = ELTO_NULO; } void DestruirAbin (Abin A) { free(A->nodos); free(A); }
int ArbolVacioB (Abin A) { return (A->nodos[0] == ELTO_NULO); } tElemento RecuperarB (nodo n, Abin A) { if (n < 0 || n > A->maxNodos - 1) ERROR(...: Nodo inexistente"); if (A->nodos[n] == ELTO_NULO) ERROR(...: Nodo inexistente"); return A->nodos[n]; } void ModificarB (nodo n, tElemento e, Abin A) { if (n < 0 || n > A->maxNodos - 1) ERROR(...: Nodo inexistente"); if (A->nodos[n] == ELTO_NULO) ERROR(...: Nodo inexistente"); A->nodos[n] = e; }
111
112
nodo RaizB (Abin A) { if (A->nodos[0] != ELTO_NULO) return 0; else return NODO_NULO; } nodo PadreB (nodo n, Abin A) { if (n < 0 || n > A->maxNodos - 1) ERROR("PadreB(): Nodo inexistente"); if (A->nodos[n] == ELTO_NULO) ERROR("PadreB(): Nodo inexistente"); if (n == 0) return NODO_NULO; else return (n - 1) / 2; }
113
nodo HijoIzqdoB (nodo n, Abin A) { nodo hizqdo; if (n < 0 || n > A->maxNodos - 1) ERROR("HijoIzqdoB(): Nodo inexistente"); if (A->nodos[n] == ELTO_NULO) ERROR("HijoIzqdoB(): Nodo inexistente"); hizqdo = 2 * n + 1; if (hizqdo > A->maxNodos - 1 || A->nodos[hizqdo] == ELTO_NULO) return NODO_NULO; else return hizqdo; }
114
nodo HijoDrchoB (nodo n, Abin A) { nodo hdrcho; if (n < 0 || n > A->maxNodos - 1) ERROR("HijoDrchoB(): Nodo inexistente"); if (A->nodos[n] == ELTO_NULO) ERROR("HijoDrchoB(): Nodo inexistente"); hdrcho = 2 * n + 2; if (hdrcho > A->maxNodos - 1 || A->nodos[hdrcho] == ELTO_NULO) return NODO_NULO; else return hdrcho; }
115
116
117
118
rbol vaco
A *A
l
119
l
120
/*-------------------------------------*/ /* Abin.h */ /*-------------------------------------*/ #define NODO_NULO NULL typedef char tElemento; /* Por ejemplo */ #ifndef _ARBOL_BINARIO_ #define _ARBOL_BINARIO_ typedef struct celda { tElemento elto; struct celda *padre, *hizq, *hder; } tipoNodo; typedef tipoNodo *nodo; typedef tipoNodo **Abin;
121
Abin CrearAbin (void); void CrearRaizB (tElemento e, Abin A); void InsertarHijoIzqdoB (nodo n, tElemento e, Abin A); void InsertarHijoDrchoB (nodo n, tElemento e, Abin A); void EliminarHijoIzqdoB (nodo n, Abin A); void EliminarHijoDrchoB (nodo n, Abin A); void EliminarRaizB (Abin A); void DestruirAbin (Abin A); int ArbolVacioB (Abin A); tElemento RecuperarB (nodo n, Abin A); void ModificarB (nodo n, tElemento e, Abin A); nodo RaizB (Abin A); nodo PadreB (nodo n, Abin A); nodo HijoIzqdoB (nodo n, Abin A); nodo HijoDrchoB (nodo n, Abin A); #endif
122
/*-----------------------------------------*/ /* Abin.c */ /*-----------------------------------------*/ #include <stdlib.h> #include "error.h" #include "abin.h" static void DestruirNodos (nodo n) { if (n != NODO_NULO) { DestruirNodos(n->hizq); DestruirNodos(n->hder); free(n); } }
Abin CrearAbin () { Abin A; A = (Abin) malloc(sizeof(tipoNodo *)); if (A == NULL) ERROR(CrearAbin(): No hay memoria); *A = NULL; return A; } void CrearRaizB (tElemento e, Abin A) { if (*A != NODO_NULO) ERROR("CrearRaiz(): rbol no vaco"); *A = (nodo) malloc(sizeof(tipoNodo)); if (*A == NULL) ERROR("CrearRaizB(): No hay memoria"); (*A)->elto = e; (*A)->padre = NODO_NULO; (*A)->hizq = NODO_NULO; (*A)->hder = NODO_NULO; }
123
124
void InsertarHijoIzqdoB (nodo n, tElemento e, Abin A) { if (n == NODO_NULO) ERROR("InsertarHijoIzqdoB(): Nodo inexistente"); if (n->hizq != NODO_NULO) ERROR("InsertarHijoIzqdoB(): Ya existe hijo izquierdo"); n->hizq = (nodo) malloc(sizeof(tipoNodo)); if (n->hizq == NULL) ERROR("InsertarHijoIzqdoB(): No hay memoria"); n->hizq->elto = e; n->hizq->padre = n; n->hizq->hizq = NODO_NULO; n->hizq->hder = NODO_NULO; }
void InsertarHijoDrchoB (nodo n, tElemento e, Abin A) { if (n == NODO_NULO) ERROR("InsertarHijoDrchoB(): Nodo inexistente"); if (n->hder != NODO_NULO) ERROR("InsertarHijoDrchoB(): Ya existe hijo derecho"); n->hder = (nodo) malloc(sizeof(tipoNodo)); if (n->hder == NULL) ERROR("InsertarHijoDrchoB(): No hay memoria"); n->hder->elto = e; n->hder->padre = n; n->hder->hizq = NODO_NULO; n->hder->hder = NODO_NULO; }
125
126
void EliminarHijoIzqdoB (nodo n, Abin A) { if (n == NODO_NULO) ERROR("EliminarHijoIzqdoB(): Nodo inexistente"); if (n->hizq == NODO_NULO) ERROR("EliminarHijoIzqdoB(): No existe hijo izquierdo"); if (n->hizq->hizq != NODO_NULO || n->hizq->hder != NODO_NULO) ERROR("EliminarHijoIzqdoB(): Hijo izquierdo no es hoja"); free(n->hizq); n->hizq = NODO_NULO; }
void EliminarHijoDrchoB (nodo n, Abin A) { if (n == NODO_NULO) ERROR(...: Nodo inexistente"); if (n->hder == NODO_NULO) ERROR(...: No existe hijo derecho"); if (n->hder->hizq != NODO_NULO || n->hder->hder != NODO_NULO) ERROR(...: Hijo drcho no es una hoja"); free(n->hder); n->hder = NODO_NULO; }
127
128
void EliminarRaizB (Abin A) { if (*A == NODO_NULO) ERROR("EliminarRaizB(): rbol vaco"); if ((*A)->hizq != NODO_NULO || (*A)->hder != NODO_NULO) ERROR(...: La raz no es un nodo hoja"); free(*A); *A = NODO_NULO; } void DestruirAbin (Abin A) { DestruirNodos(*A); free(A); }
int ArbolVacioB (Abin A) { return (*A == NODO_NULO); } tElemento RecuperarB (nodo n, Abin A) { if (n == NODO_NULO) ERROR("RecuperarB(): Nodo inexistente"); return n->elto; } void ModificarB (nodo n, tElemento e, Abin A) { if (n == NODO_NULO) ERROR("ModificarB(): Nodo inexistente"); n->elto = e; }
129 130
nodo RaizB (Abin A) { return *A; } nodo PadreB (nodo n, Abin A) { if (n == NODO_NULO) ERROR("PadreB(): Nodo inexistente"); return n->padre; } nodo HijoIzqdoB (nodo n, Abin A) { if (n == NODO_NULO) ERROR("HijoIzqdoB(): Nodo inexistente"); return n->hizq; } nodo HijoDrchoB (nodo n, Abin A) { if (n == NODO_NULO) ERROR("HijoDrchoB(): Nodo inexistente"); return n->hder; }
En profundidad f g h j i a k c e l b d j h i g
En anchura f b a k c e l d
131
132
g
Ai Ad h
a i
d
c e
Preorden(f) = f Preorden(g) Preorden(b) = f g Preorden(h) Preorden(a) Preorden(b) = f g h Preorden(j) Preorden(a) Preorden(b) = f g h j Preorden(a) Preorden(b) = f g h j a Preorden(i) Preorden(k) Preorden(b) = f g h j a i Preorden(k) Preorden(b) = f g h j a i k Preorden(b) = f g h j a i k b Preorden(d) = f g h j a i k b d Preorden(e) = f g h j a i k b d e Preorden(c) Preorden(l) = f g h j a i k b d e c Preorden(l) = fghjaikbdecl
133
134
b d
c l
Inorden(f) = Inorden(g) f Inorden(b) = Inorden(h) g Inorden(a) f Inorden(b) = Inorden(j) h g Inorden(a) f Inorden(b) = j h g Inorden(a) f Inorden(b) = j h g Inorden(i) a Inorden(k) f Inorden(b) = j h g i a Inorden(k) f Inorden(b) = j h g i a k f Inorden(b) = j h g i a k f b Inorden(d) = j h g i a k f b Inorden(e) d = j h g i a k f b Inorden(c) e Inorden(l) d = j h g i a k f b c e Inorden(l) d = jhgiakfbceld
f g h j
a i
c l
Postorden(f) = Postorden(g) Postorden(b) f = Postorden(h) Postorden(a) g Postorden(b) f = Postorden(j) h Postorden(a) g Postorden(b) f = j h Postorden(a) g Postorden(b) f = j h Postorden(i) Postorden(k) a g Postorden(b) f = j h i Postorden(k) a g Postorden(b) f = j h i k a g Postorden(b) f = j h i k a g Postorden(d) b f = j h i k a g Postorden(e) d b f = j h i k a g Postorden(c) Postorden(l) e d b f = j h i k a g c Postorden(l) e d b f = jhikagcledbf
135
136
void PreordenAbin (nodo n, Abin A, void (*Procesar)(nodo, Abin)) /* Recorrido en preorden del subrbol cuya raz es el nodo n perteneciente al rbol binario A. Cada nodo visitado se procesa mediante la funcin Procesar() */ { if (n != NODO_NULO) { Procesar(n, A); PreordenAbin(HijoIzqdoB(n, A), A, Procesar); PreordenAbin(HijoDrchoB(n, A), A, Procesar); } }
void InordenAbin (nodo n, Abin A, void (*Procesar)(nodo, Abin)) { if (n != NODO_NULO) { InordenAbin(HijoIzqdoB(n, A), A, Procesar); Procesar(n, A); InordenAbin(HijoDrchoB(n, A), A, Procesar); } }
137
138
void PostordenAbin (nodo n, Abin A, void (*Procesar)(nodo, Abin)) { if (n != NODO_NULO) { PostordenAbin(HijoIzqdoB(n, A), A, Procesar); PostordenAbin(HijoDrchoB(n, A), A, Procesar); Procesar(n, A); } }
139