LibroEstructurasOrganizacionDatos PDF
LibroEstructurasOrganizacionDatos PDF
ESTRUCTURAS Y ORGANIZACIÓN DE
DATOS
de la Ingenierı́a en TICs
Índice de tablas V
1.1. Definición . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.2. Clasificación . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
i
ÍNDICE GENERAL
2. Estructuras lineales 31
2.1. Listas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
2.4. Aplicaciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
ITPuebla ii
ÍNDICE GENERAL
4.3. Medición Teórica del Tiempo de Ejecución de los Algoritmos de Ordenamiento y Búsqueda20
ITPuebla iii
ÍNDICE GENERAL
Bibliografı́a 270
ITPuebla iv
Índice de tablas
4.2. Archivo de los alumnos del Tec–Puebla, con registros ordenados de acuerdo al número de con
4.3. Archivo de los alumnos del Tec–Puebla, con registros ordenados de acuerdo al apellido.178
v
ÍNDICE DE TABLAS
ITPuebla vi
Índice de figuras
1.4. Definición de O . . . . . . . . . . . . . . . . . . . . . . . . . . 15
vii
ÍNDICE DE FIGURAS
ITPuebla viii
ÍNDICE DE FIGURAS
2.29. Interfaz Cola implementada con una cola circular con vector . 84
2.33. Interfaz Cola implementada con una cola doble con vector . . 90
2.41. Pila para convertir notación infija a posfija con un operador . 102
2.42. Pila para convertir notación infija a posfija con dos operadores 103
2.43. Notación infija a posfija con dos operadores en diferente orden 103
2.45. Diagrama de clases para el control de un cajero con una cola 106
3.5. Grafo utilizado para representar una red de estados de la región oriente e la República Mexic
ITPuebla ix
ÍNDICE DE FIGURAS
3.8. Inserción de nodos (b) y lados (c) en un grafo, con matrices de adyascencia A e incidencia I 1
3.9. Eliminación de nodos (a) y lados (b) en un grafo, con matrices de adyascencia A e incidencia
3.16. Recorrido a lo ancho de un Grafo, agregar el nodo al recorrido y marcarlo como visitado140
3.18. Grafo dirigido para representar el orden en que Batman debe ponerse la ropa [17]143
3.19. Grafo ponderado para representar una red de estados de la región oriente e la República Mex
3.20. Grafo dirigido y ponderado, con tres posibles caminos entre Hidalgo y Guerrero, siendo el m
3.21. Ejemplo de funcionamiento del algoritmo de Dijkstra para calcular el costo mı́nimo de 566 K
3.22. Ejemplos de grafos que no son árboles (a) y (b), y que sı́ lo son (c) y (d)150
3.25. Árboles de aridad tres (a), y aridad dos (árboles binarios) (b) 153
3.27. Recorrido (a) a lo ancho (por niveles), y (b) a lo largo (a lo profundo), de un árbol de búsque
ITPuebla x
ÍNDICE DE FIGURAS
3.32. Eliminar un nodo hoja (Costa) y un nodo con un sólo hijo (Serrat) en un árbol de búsqueda
3.38. Árboles de búsqueda de altura máxima y mı́nima que almacenan los mismos datos174
3.39. Árboles de búsqueda de altura máxima y mı́nima que almacenan los mismos datos175
4.1. Ordenamiento de los registros de un archivo por dirección, de acuerdo al número de control y
4.3. Ejemplo de implementación de ordenamiento de datos por el Método del Ordenamiento Rápi
4.4. Ejemplo de implementación de ordenamiento de datos por el Método del Ordenamiento por C
4.5. Ejemplo de implementación de ordenamiento de datos por el Método del Ordenamiento por C
ITPuebla xi
ÍNDICE DE FIGURAS
4.13. Esquema de la ejecución del Algoritmo 120 que da de alta un registro al final de un Archivo S
4.14. Esquema de la ejecución del Algoritmo 121 que da de alta un registro al inicio de un Archivo
4.15. Esquema de la ejecución del Algoritmo 122 que inserta un nuevo registro en la posición lógica
4.16. Esquema de la ejecución del Algoritmo 123 que elimina el primer registro de un Archivo Secu
4.17. Esquema de la ejecución del Algoritmo 124 que elimina el último registro de un Archivo Secu
4.19. Ejemplo de la inserción de una pareja {clave, dirRelativa} en una Tabla de Directorio240
4.20. Ejemplo de la eliminación de una pareja {clave, dirRelativa} en una Tabla de Directorio.241
4.21. Ejemplo de organización de registros en un Archivo Directo con transformación de claves med
4.22. Ejemplo de organización de registros en un Archivo Directo con transformación de claves med
4.23. Ejemplo de uso de una Tabla de Acceso Directo como estructura de datos auxiliar para el acc
4.24. Ejemplo de uso de una Tabla Hash como estructura de datos auxiliar para el acceso a un Arc
4.25. Ejemplo de uso de una tabla de dispersión como estructura de datos auxiliar para el acceso a
4.26. Ejemplo del Método de la Dispersión Abierta para resolver colisiones cuando se utiliza una T
ITPuebla xii
Índice de algoritmos
1. sumaVec(v:int[n], w:int[n]):int[n] . . . . . . . . . . . 24
2. sumaMat(A:int[n][n],B:int[n][n]):int[n][n] . . . . . . 25
3. multiplicaMat(A:int[n][n],B:int[n][n]):int[n][n] . . 25
4. busca(v:char[n],carac:char):int . . . . . . . . . . . . . 27
5. muestraDesde(carac:char):void . . . . . . . . . . . . . . . 28
6. sumaVecIterativo(v:int[n],w:int[n]):int[n] . . . . . . 29
7. sumaVecRecursivo(v:int[n],w:int[n],n,i:int):int[n] 30
8. ListaSimple() . . . . . . . . . . . . . . . . . . . . . . . . . 39
9. ListaSimple(cab:NodoSimple) . . . . . . . . . . . . . . . . 40
10. esVacia():booleano . . . . . . . . . . . . . . . . . . . . . . 40
11. insertarCabeza(dato:Object):Object . . . . . . . . . . . 40
12. insertarFinal(dato:Object):Object . . . . . . . . . . . . 41
13. insertarPosi(dato:Object, posi:int):Object . . . . . . 43
14. eliminarCabeza():Object . . . . . . . . . . . . . . . . . . . 44
15. eliminarFinal():Object . . . . . . . . . . . . . . . . . . . 45
16. eliminarPosi(posi:int):Object . . . . . . . . . . . . . . . 46
17. recorrer():VectorObject . . . . . . . . . . . . . . . . . . . 48
18. verFinal():Object . . . . . . . . . . . . . . . . . . . . . . . 48
19. verCabeza():Object . . . . . . . . . . . . . . . . . . . . . . 50
20. verPosi(posi:int):Object . . . . . . . . . . . . . . . . . . 50
21. insertarCabeza(dato:Object):Object . . . . . . . . . . . 53
22. insertarCabeza(dato:Object):Object . . . . . . . . . . . 53
23. recorrerUltimoPrimero():VectorObject . . . . . . . . . . 54
24. PilaVector() . . . . . . . . . . . . . . . . . . . . . . . . . . 62
25. PilaVector(longitud:int) . . . . . . . . . . . . . . . . . . 63
26. esVacia(): booleano . . . . . . . . . . . . . . . . . . . . . 63
27. esLlena(): booleano . . . . . . . . . . . . . . . . . . . . . 63
28. push(dato: Objeto): Objeto . . . . . . . . . . . . . . . . . 64
29. pop(): Objeto . . . . . . . . . . . . . . . . . . . . . . . . . 64
xiii
ÍNDICE DE ALGORITMOS
ITPuebla xiv
ÍNDICE DE ALGORITMOS
70. invierteVector(vec[n]):vec[n] . . . . . . . . . . . . . . . 97
71. invierteVectorConPila(vec[n]):vec[n] . . . . . . . . . . 98
72. verificaParen():boolean . . . . . . . . . . . . . . . . . . . 101
73. despachaClientes(): void . . . . . . . . . . . . . . . . . . 106
74. calculaFactorialIterativo(n:int):long . . . . . . . . . 109
75. calculaFactorialRecursivo(n:int):long . . . . . . . . . 109
76. buscaIterat(v:Object[n],n:int,dato:Object):boolean 113
77. buscaRecur1(v:Object[n],i:int,n:int,dato:Object) . . 114
78. buscaRecur2(v:Object[],ini,fin,n:int,dato:Object) . 115
79. sumaRecursivoPrimeroResto(v:int[n],n:int,i:int) . . 118
80. sumaRecursivoDivideVenceras(v:int[n],n:int,i:int) . 118
81. GrafoNoDirigido() . . . . . . . . . . . . . . . . . . . . . . . 132
82. insertarNodo(nodo:String):String . . . . . . . . . . . . . 133
83. insertarLado(lado,n1,n2:String):String . . . . . . . . . 134
84. eliminarNodo(nodo:String):String . . . . . . . . . . . . . 135
85. eliminarLado(lado:String):String . . . . . . . . . . . . . 136
86. recorrerAncho(nodoFuente:String):Vector<String> . . 137
87. recorrerLargo(nodoFuente:String):Vector<String> . . 142
88. dijkstra(nodoFuente:String,nodoDestino:String):int 148
89. ArbolBusqueda() . . . . . . . . . . . . . . . . . . . . . . . . 166
90. esVacio():boolean . . . . . . . . . . . . . . . . . . . . . . . 167
91. buscarNodo(dato:String,raiz,padreRaiz:Nodo):Vector<Nodo> 167
92. insertarNodo(dato:String):String . . . . . . . . . . . . . 168
93. eliminarNodo(dato:String):String . . . . . . . . . . . . . 169
94. eliminarHoja(padreAux,aux:Nodo):void . . . . . . . . . . 170
95. eliminarHijoIzq(dato:String):String . . . . . . . . . . . 170
96. eliminarHijoDer(dato:String):String . . . . . . . . . . . 171
97. buscaPredecesor(aux:Nodo):String . . . . . . . . . . . . . 171
98. recorrerEnorden(raiz:Nodo):Vector<String> . . . . . . 172
99. recorrerPreorden(raiz:Nodo):Vector<String> . . . . . . 172
100. recorrerPostorden(raiz:Nodo):Vector<String> . . . . . 173
101. insercionDirecta(A:Object[N]):Object[N] . . . . . . . . 181
102. insercionDirectaGralizada(A:Object[N]):Object[N] . . 184
103. burbuja(A:Object[N]):Object[N] . . . . . . . . . . . . . . 186
104. quickSort(A:Object[N],p:int,u:int):Object[N] . . . . 190
105. concatenación(A:Object[N]):Object[N] . . . . . . . . . . 193
106. concatenar(A:Object[N],i1,f1,i2,f2:int):Object[N] . 194
107. selecciónDirecta(A:Object[N]):Object[N] . . . . . . . . 197
108. montı́culo(A:Object[N]):Object[N] . . . . . . . . . . . . . 201
109. insertarEnMontı́culo(A:Object[N]):Object[N] . . . . . . 202
ITPuebla xv
ÍNDICE DE ALGORITMOS
ITPuebla xvi
Capı́tulo 1
Fundamentos de estructura
de datos
1
1.1. DEFINICIÓN
1.1. Definición
ITPuebla 2
1.2. CLASIFICACIÓN
1.2. Clasificación
ITPuebla 3
1.3. ESTRUCTURAS LINEALES Y NO LINEALES
pio tipo de dato, o bien todos los componentes pueden ser del mismo
tipo de dato. Con esto, se tienen dos tipos de estructuras de datos:
ITPuebla 4
1.4. ESTRUCTURAS ESTÁTICAS Y DINÁMICAS
ITPuebla 5
1.4. ESTRUCTURAS ESTÁTICAS Y DINÁMICAS
ITPuebla 6
1.5. TIPOS DE DATOS ABSTRACTOS (TDA)
ITPuebla 7
1.5. TIPOS DE DATOS ABSTRACTOS (TDA)
• Encabezado (Abstract).
• Precondiciones (Precondition).
• Postcondiciones (Postcondition).
Definición de valores:
Abstract typedef <Val> <Id>
Condition <Cond1>;<Cond2>;...;<Condn>
Definición de operaciones:
Abstract <tipo> <op> (<arg1>,<arg2>,...,<argm>)
Precondition <ConP1>;<ConP2>;...; <ConPp>
Postcondition <ConQ1>;<ConQ2>;...;<CondQq>;
<op> := <resul>
donde:
<arg>: operandos con los que se trabaja en la operación que se está de-
finiendo
ITPuebla 8
1.6. ANÁLISIS DE ALGORITMOS
Definición de valores:
Abstract typedef <subconjunto de Z> int
Definición de operaciones:
Abstract int +(int a, int b)
Postcondition + := a+b
Abstract int *(int a, int b)
Postcondition * := a*b
Abstract int -(int a, int b)
Postcondition - := a-b
Abstract int div(int a, int b)
Precondition b <>0
Postcondition div := a/b
ITPuebla 9
1.6. ANÁLISIS DE ALGORITMOS
Corrección.
Sencillez y claridad.
Optimidad.
ITPuebla 10
1.6. ANÁLISIS DE ALGORITMOS
Instrucciones
Constantes
Variables
Datos de entrada
ITPuebla 11
1.6. ANÁLISIS DE ALGORITMOS
ITPuebla 12
1.6. ANÁLISIS DE ALGORITMOS
el peor caso serı́a buscar a Helena (que está al final del arreglo) o a
Alberto (que no está); mientras que el mejor caso serı́a buscar a Luis.
ITPuebla 13
1.6. ANÁLISIS DE ALGORITMOS
Notación asintótica
Definición de O. Sean t(n) y f (n) dos funciones arbitrarias tales que [2][15]:
t(n), f (n) ∶ Z → R ,
+ +
t(n) ≤ cf (n),
Por ejemplo, sean t(n) = 3n+2 y f (n) = n, entonces t(n) = O(f (n)) porque:
3n = 3n
3n + 2 ≤ 3n + n, para n ≥ 2
3n + 2 ≤ 4n, para n ≥ 2,
ITPuebla 14
1.6. ANÁLISIS DE ALGORITMOS
ITPuebla 15
1.6. ANÁLISIS DE ALGORITMOS
2 n
Figura 1.6: Contraste gráfico de n y 2
ITPuebla 16
1.6. ANÁLISIS DE ALGORITMOS
2 n
Figura 1.7: Detalle de contraste gráfico de n y 2
ITPuebla 17
1.6. ANÁLISIS DE ALGORITMOS
Jerarquı́a de funciones
ITPuebla 18
1.6. ANÁLISIS DE ALGORITMOS
ITPuebla 19
1.6. ANÁLISIS DE ALGORITMOS
Operaciones aritméticas.
Operaciones lógicas.
ITPuebla 20
1.6. ANÁLISIS DE ALGORITMOS
Regla de la suma.
Tbloque (n) = Tsentencia1 (n) + Tsentencia2 (n) = O(máx{f (n), g(n)}). (1.4)
ITPuebla 21
1.6. ANÁLISIS DE ALGORITMOS
Titeración (n) = Tbloq ini (n) + Tbloq ini+1 (n) + ... + Tbloq fin (n) =
= O((f in − ini + 1) ∗ máx{fini (n) + fini+1 (n) + ... + ffin (n), }
(1.6)
ITPuebla 22
1.6. ANÁLISIS DE ALGORITMOS
void alg1 ()
{ bloque1; Tbloq1 (n) = O(f (n))
alg2(); Talg2 (n) = O(g(n))
bloque2; Tbloq2 (n) = O(h(n))
alg3(); Talg3 (n) = O(p(n))
}
i=1 i=1
ITPuebla 23
1.6. ANÁLISIS DE ALGORITMOS
entonces se puede decir que el algoritmo que suma dos vectores de tamaño
n es de orden lineal:
T (n) = n = O(n).
j=1 i=1
con esto, el bloque de sentencias del ciclo externo controlado por i, consiste
de una sentencia iterativa (controlada por j, del ciclo interno) con tiempo
de ejecución:
Titerj (n) = n.
Ahora, para calcular el tiempo de ejecución del ciclo externo, se vuelve a
utilizar la ecuación (1.7):
i=1 i=1
ITPuebla 24
1.6. ANÁLISIS DE ALGORITMOS
entonces se puede decir que el algoritmo que suma dos matrices de tamaño
n × n es de orden cuadrático:
T (n) = n = O(n ).
2 2
Algoritmo 2 sumaMat(A:int[n][n],B:int[n][n]):int[n][n]
no n × n **
/* Suma dos matrices de tama~
** Entradas: **
** A:int[n][n] **
** B:int[n][n] **
** Salidas: **
** A:int[n][n] */
Tcondi (n) = 1 Titeri (n) = n
2
1. Para i=1,2,...,n
2. Para j=1,2,...,n Tcondj (n) = 1 Titerj (n) = n
3. A[i][j]=A[i][j]+B[i][j] Tbloq (n) = 1
Algoritmo 3 multiplicaMat(A:int[n][n],B:int[n][n]):int[n][n]
/* Multiplica dos matrices de tama~ no n × n **
** Entradas: **
** A:int[n][n] **
** B:int[n][n] **
** Salidas: **
** C:int[n][n] */
Tcondi (n) = 1, Titeri (n) = n
3
1. Para i=1,2,...,n
Tcondj (n) = 1, Titerj (n) = n
2
2. Para j=1,2,...,n
3. C[i][j]=0 Tpaso1 (n) = 1
4. Para k=1,2,...,n Tcondk (n) = 1, Titerk (n) = n
3. C[i][j]=C[i][j]+A[i][k]*B[k][j] Tpaso2 (n) = 1
4. Return C Tpaso3 (n) = 1
ITPuebla 25
1.6. ANÁLISIS DE ALGORITMOS
j=1 j=1
i=1 i=1
1 2 3 4 5 6 7 8 9 10
’b’ ’s’ ’w’ ’r’ ’q’ ’m’ ’t’ ’x’ ’h’ ’y’
5 6 7 8 9 10
’q’ ’m’ ’t’ ’x’ ’h’ ’y’
ITPuebla 26
1.6. ANÁLISIS DE ALGORITMOS
posi
n n
= ∑ máx{1, 1} = ∑ 1 = n − posi + 1;
posi posi
Algoritmo 4 busca(v:char[n],carac:char):int
/* Busca la posición que tiene un caracter en un vector **
no n. Si el caracter no se encuentra,
/* de tama~ **
/* el algoritmo retorna -1 **
** Entradas: **
** v:char[n] **
** carac:char **
** Salidas: **
** posi:int */
ITPuebla 27
1.6. ANÁLISIS DE ALGORITMOS
Algoritmo 5 muestraDesde(carac:char):void
/* Muestra los caracteres de un vector de tama~ no n **
/* a partir de la posición que ocupa un caracter dado **
** Entradas: **
** v:char[n] **
** carac:char **
** Salidas: **
** ninguna */
1. posi = busca(carac) Tbusca (n) = n
2. Si posi != -1 Tdeci (n) = n − posi + 1
3. Para i=posi,posi+1,...,n Titeri (n) = n − posi + 1
4. Print (v[i]) Tpaso1 (n) = 1
verdad, ya que:
ITPuebla 28
1.6. ANÁLISIS DE ALGORITMOS
Algoritmos no recursivos
Núm. de variables Cantidad de memoria Complejidad
c variables escalares T (n) = c = O(1) Constante
c vectores de tamaño n T (n) = cn = O(n) Lineal
Algoritmos recursivos
Núm. de llamados/variables Cantidad de memoria Complejidad
n llamadas recursivas con T (n) = cn = O(n) Lineal
c variables escalares
T (n) = cnn = O(n )
2
n llamadas recursivas con Cuadrática
c vectores de tamaño n
Algoritmo 6 sumaVecIterativo(v:int[n],w:int[n]):int[n]
/* Suma iterativamente dos vectores de tama~ no n **
** Entradas: **
** v,w:int[n] **
** Salidas: **
** v:int[n] */
1. Para i=1,2,...,n Tcond (n) = 1 Titer (n) = n
2. v[i] = v[i] + w[i] Tbloq (n) = 1
ITPuebla 29
1.6. ANÁLISIS DE ALGORITMOS
Algoritmo 7 sumaVecRecursivo(v:int[n],w:int[n],n,i:int):int[n]
no n **
/* Suma recursivamente dos vectores de tama~
** Entradas: **
** v,w:int[n] **
** n,i:int **
** Salidas: **
** v:int[n] */
1. Si i<n
2. v[i] = v[i]+w[i]
3. sumaVecRecursivo(v,w,n,i+1)
ITPuebla 30
Capı́tulo 2
Estructuras lineales
2.1. Listas
31
2.1. LISTAS
Una lista ligada puede verse gráficamente en la Figura 2.1, donde se tiene
una lista ligada de 4 nodos, el primero de ellos es el nodo cabeza, el último
apunta a null. La lista tiene una referencia al primer nodo, al nodo cabeza,
en la Figura esta referencia se llama cabeza. Para acceder al cualquier nodo
debe hacerce referencia al nodo cabeza.
Cada nodo de una lista simple tiene dos componentes (ver Figura 2.2)
que son dos referencias (también llamados apuntadores o direcciones de me-
moria): una referencia al dato que almacena el nodo, y una referencia al
siguiente nodo.
ITPuebla 32
2.1. LISTAS
Definición de valores
int
Abstract typedef <algúnTipo> Lista
Definición de operaciones
Abstract <algúnTipo> insertarCabeza (Lista lis,
<algúnTipo> componente)
Postcondition
ligar componente con el nodo cabeza de lis
la nueva cabeza es componente
lis tiene un componente más
inertarCabeza := componente
ITPuebla 33
2.1. LISTAS
Definición de operaciones
Abstract <algúnTipo> insertarFinal (Lista lis,
<algúnTipo> componente)
Postcondition
ligar componente como siguiente nodo
del nodo final de lis
lis tiene un componente más
insertarFinal := componente
Definición de operaciones
Abstract <algúnTipo> insertarPosi (Lista lis,
<algúnTipo> componente, int posi)
Precondition
lis tiene al menos el nodo posi-1
posi ≥ 0
Postcondition
ligar componente como siguiente nodo
del nodo posi-1 y como nodo anterior
del nodo posi+1 de lis
lis tiene un componente más
insertarPosi := componente
Definición de operaciones
Abstract <algúnTipo> eliminarCabeza (Lista lis)
Precondition
lis no está vacı́a
Postcondition
eliminarCabeza := componente de la cabeza de lis
nueva cabeza de lis es el segundo nodo
lis tiene un componente menos
Definición de operaciones
Abstract <algúnTipo> eliminarFinal (Lista lis)
Precondition
lis no está vacı́a
Postcondition
eliminarFinal := componente del nodo final de lis
lis tiene un componente menos
ITPuebla 34
2.1. LISTAS
Definición de operaciones
Abstract <algúnTipo> eliminarPosi (Lista lis, int posi)
Precondition
lis no está vacı́a
lis tiene al menos el nodo posi
posi ≥ 0
Postcondition
eliminarPosi := componente del nodo de la posición
posi de lis
lis tiene un componente menos
Definición de operaciones
Abstract boolean esVacı́a (Lista lis)
Postcondition
esVacı́a := true si lis no tiene componentes
esVacı́a := false si lis tiene al menos un componente
Definición de operaciones
Abstract Vector<Object>recorrer (Lista lis)
Postcondition
recorrer := todos los componentes de lis en un
vector de objetos
Definición de operaciones
Abstract <algúnTipo>verCabeza (Lista lis)
Precondition
lis no es vacı́a
Postcondition
verCabeza := componente de la cabeza de lis
Definición de operaciones
Abstract <algúnTipo>verFinal (Lista lis)
Precondition
lis no es vacı́a
Postcondition
verFinal := componente del nodo final de lis
ITPuebla 35
2.1. LISTAS
Definición de operaciones
Abstract <algúnTipo>verPosi (Lista lis, int posi)
Precondition
lis no es vacı́a
lis tiene al menos el nodo posi
Postcondition
verPosi := componente del nodo de la posición
posi de lis
ITPuebla 36
2.1. LISTAS
Tabla 2.1: Ejemplos de operaciones básicas con una lista ligada simple
No. de Operación(Entrada) Salida Lista
paso
1 ninguna ninguna [null] (lista vacı́a)
2 insertarCabeza(3) 3 [3→null]
3 insertarCabeza(7) 7 [7→3→null]
4 insertarFinal(5) 5 [7→3→5→null]
5 insertarPosi(9,1) 9 [7→9→3→5→null]
6 verFinal() 5 [7→9→3→5→null]
7 verPosi(3) 5 [7→9→3→5→null]
8 esVacia() false [7→9→3→5→null]
9 recorrer() [7,9,3,5] [7→9→3→5→null]
10 eliminarCabeza() 7 [9→3→5→null]
11 eliminarPosi(2) 5 [9→3→null]
12 insertarPosi(8,5) null [9→3→null]
13 eliminarFinal() 3 [9→null]
14 verPosi(2) null [9→null]
15 eliminarFinal() 9 [null]
16 esVacia() true [null]
ITPuebla 37
2.1. LISTAS
Con esta interfaz se puede implementar una lista ligada simple, como
en el diagrama de clases de la Figura 2.5. La ListaSimple implementa la
interfaz Lista, y está compuesta por un conjunto de objetos de la clase
NodoSimple.
ITPuebla 38
2.1. LISTAS
Algoritmo 8 ListaSimple()
/* Constructor, inicializa/instancia variables/objetos **
** atributos de la clase, con valores por defecto **
** Entradas: **
** ninguna **
** Salidas: **
** ninguna */
1. cabeza=null
ITPuebla 39
2.1. LISTAS
Algoritmo 9 ListaSimple(cab:NodoSimple)
/* Constructor, inicializa/instancia variables/objetos **
** atributos de la clase con valores de argumentos **
** Entradas: **
** cab: NodoSimple, referencia a un nodo simple **
** Salidas: **
** ninguna */
1. cabeza=cab
Algoritmo 10 esVacia():booleano
/* Verifica si la lista está vacı́a **
** Regresa true si la lista está vacı́a **
** Regresa false en caso contrario **
** Entradas: **
** ninguna **
** Salidas: **
** un booleano */
1. Si cabeza=null
2. Return true
3. Sino
4. Return false
Algoritmo 11 insertarCabeza(dato:Object):Object
/* Inserta un dato (nodo) en la cabeza de la lista **
** Retorna el dato **
** Entradas: **
** dato:Object, dato a insertar **
** Salidas: **
** dato:Object, dato insertado **
** Variables/Objetos locales: **
** nuevoNodo:NodoSimple */
1. nuevoNodo=new NodoSimple(dato,null)
2. Si esVacia()
3. cabeza=nuevoNodo
4. Sino
5. nuevoNodo.setSig(cabeza)
6. cabeza=nuevoNodo
7. Return dato
ITPuebla 40
2.1. LISTAS
Algoritmo 12 insertarFinal(dato:Object):Object
/* Inserta un dato como nodo final de la lista. **
** Retorna el dato **
** Entradas: **
** dato:Object, dato a insertar **
** Salidas: **
** dato:Object, dato insertado **
** Variables/Objetos locales: **
** nuevoNodo:NodoSimple **
** aux:NodoSimple */
1. nuevoNodo=new NodoSimple(dato, null)
2. Si esVacia()
3. cabeza=nuevoNodo
4. Sino
5. aux=cabeza
6. Mientras aux.getSig()≠null
7. aux=aux.getSig()
8. aux.setSig(nuevoNodo)
9. Return dato
ITPuebla 41
2.1. LISTAS
ITPuebla 42
2.1. LISTAS
ITPuebla 43
2.1. LISTAS
Algoritmo 14 eliminarCabeza():Object
/* Elimina el dato de la cabeza de la lista. Lo retorna **
** Entradas:
** ninguna **
** Salidas: **
** dato:Object, dato eliminado **
** Variables/Objetos locales: **
** dato:Object */
1. Si esVacia()
2. Return null
3. Sino
4. dato=cabeza.getDato()
5. cabeza=cabeza.getSig()
6. Return dato
ITPuebla 44
2.1. LISTAS
Algoritmo 15 eliminarFinal():Object
/* Elimina el dato del nodo final de la lista **
** y lo retorna. **
** Entradas: **
** ninguna **
** Salidas: **
** dato:Object, dato eliminado **
** Variables/Objetos locales: **
** dato:Object **
** ultimo:NodoSimple **
** penultimo:NodoSimple */
1. Si esVacia()
2. Return null
3. Sino
4. ultimo=cabeza
5. penultimo=null
6. Mientras ultimo.getSig()≠null
7. penultimo=ultimo
8. ultimo=ultimo.getSig()
9. dato=ultimo.getDato()
10. Si penultimo=null
11. cabeza=null
12. Sino
13. penultimo.setSig(null)
14. Return dato
ITPuebla 45
2.1. LISTAS
Algoritmo 16 eliminarPosi(posi:int):Object
/* Elimina el dato del nodo de la posición posi de la **
** lista y lo retorna **
** Entradas: **
** posi:int **
** Salidas: **
** dato:Object, dato eliminado **
** Variables/Objetos locales: **
** dato:Object **
** ultimo:NodoSimple **
** penultimo:NodoSimple */
1. Si esVacia()
2. Return null
3. Sino
4. Si posi=0
5. dato=cabeza.getDato()
6. cabeza=cabeza.getSig()
7. Return dato
8. Sino
9. ultimo=cabeza
10. penultimo=null
11. Mientras(posi>0)&&(ultimo≠null)
12. penultimo=ultimo
13. ultimo=ultimo.getSig()
14. posi--
15. Si ultimo=null
16. Return null
17. Sino
18. dato=ultimo.getDato()
19. penultimo.setSig(ultimo.setSig())
20. Return dato
ITPuebla 46
2.1. LISTAS
ITPuebla 47
2.1. LISTAS
Algoritmo 17 recorrer():VectorObject
/* Recorre los elementos de la lista desde el primero **
** hasta el último, asignándolos a un vector y **
** lo retorna **
** Entradas: **
** ninguna **
** Salidas: **
** vec:Vector<Object> **
** Variables/Objetos locales: **
** aux:NodoSimple */
1. Si esVacia()
2. Return null
3. Sino
4. aux=cabeza
5. Mientras(aux≠null)
6. vec=vec.add(aux.getDato())
7. aux=aux.getSig()
8. Return vec
Algoritmo 18 verFinal():Object
/* Consulta y regresa el dato del nodo final **
** Entradas: **
** ninguna **
** Salidas: **
** dato:Object, dato consultado **
** Variables/Objetos locales: **
** ultimo:NodoSimple **
1. Si esVacia()
2. Return null
3. Sino
4. ultimo=cabeza
5. Mientras ultimo.getSig()≠null
6. ultimo=ultimo.getSig()
5. Return ultimo.getDato()
ITPuebla 48
2.1. LISTAS
ITPuebla 49
2.1. LISTAS
Algoritmo 19 verCabeza():Object
/* Consulta y regresa el dato del nodo cabeza (primer **
** nodo) **
** Entradas: **
** ninguna **
** Salidas: **
** dato:Object, dato consultado **
1. Si esVacia()
2. Return null
3. Sino
4. Return cabeza.getDato()
Algoritmo 20 verPosi(posi:int):Object
/* Consulta y retorna el dato del nodo de la posición **
** posi de la lista y lo retorna **
** Entradas: **
** posi:int **
** Salidas: **
** dato:Object, dato eliminado **
** Variables/Objetos locales: **
** dato:Object **
** aux:NodoSimple */
1. Si esVacia()
2. Return null
3. Sino
4. Si posi=0
5. Return cabeza.getDato()
6. Sino
7. aux=cabeza
8. Mientras (posi>0)&&(aux≠null)
9. aux=aux.getSig()
10. posi--
11. Si aux=null
12. Return null
13. Sino
14. Return aux.getDato()
ITPuebla 50
2.1. LISTAS
Además de las listas ligadas simples, se pueden manejar las listas ligadas
dobles y las listas ligadas circulares.
Una lista ligada doble (lista doblemente enlazada) es una lista donde
cada nodo (o nodo doble) es un objeto que almacena una referencia a un
elemento, una referencia al nodo siguiente y una referencia al nodo anterior
en el ordenamiento linea [5][9][14][6].
El acceso a los nodos de una lista ligada doble se realiza mediante una
referencia al primer nodo llamado cabeza, el que apunta a null en su ferencia
al nodo anterior (ya que éste no existe en la lista). El último nodo de la lista,
al no haber siguiente nodo, apunta a null en su referencia al siguiente nodo.
ITPuebla 51
2.1. LISTAS
Tabla 2.2: Ejemplos de operaciones básicas con una lista ligada doble
No. de Operación Salida Lista
paso (Entrada)
1 ninguna ninguna [null] (lista vacı́a)
2 insertarCabeza(3) 3 [3↔null]
3 insertarCabeza(7) 7 [7↔3↔null]
4 insertarFinal(5) 5 [7↔3↔5↔null]
5 insertarPosi(9,1) 9 [7↔9↔3↔5↔null]
6 verFinal() 5 [7↔9↔3↔5↔null]
7 verPosi(3) 5 [7↔9↔3↔5↔null]
8 esVacia() false [7↔9↔3↔5↔null]
9 eliminarCabeza() 7 [9↔3↔5↔null]
10 eliminarPosi(2) 5 [9↔3↔null]
11 insertarPosi(8,5) null [9↔3↔null]
12 eliminarFinal() 3 [9↔null]
13 verPosi(2) null [9↔null]
14 eliminarFinal() 9 [null]
15 esVacia() true [null]
Una lista ligada circular (lista enlazada circular) es una lista simple
donde el último nodo hace referencia al primer nodo de la lista (cabeza). A
diferencia de las otras listas, en una lista circular ningún nodo hace referencia
a null (ver Figura 2.13) [20][5][9][14][6].
El acceso a los nodos de una lista ligada circular se realiza mediante una
referencia al nodo cabeza. Cada nodo de esta lista tiene la misma estructura
que los de una lista simple (nodo simple).
ITPuebla 52
2.1. LISTAS
Algoritmo 21 insertarCabeza(dato:Object):Object
/* Inserta un dato (nodo) en la cabeza de una lista **
** doble. Retorna el dato **
** Entradas: **
** dato:Object, dato a insertar **
** Salidas: **
** dato:Object, dato insertado **
** Variables/Objetos locales: **
** nuevoNodo:NodoDoble */
1. nuevoNodo=new NodoDoble(dato,null,null)
2. Si esVacia()
3. cabeza=nuevoNodo
4. Sino
5. nuevoNodo.setSig(cabeza)
6. cabeza.setAnt(nuevoNodo)
7. cabeza=nuevoNodo
8. Return dato
Algoritmo 22 insertarCabeza(dato:Object):Object
/* Inserta un dato (nodo) en la cabeza de una lista **
** circular. Retorna el dato **
** Entradas: **
** dato:Object, dato a insertar **
** Salidas: **
** dato:Object, dato insertado **
** Variables/Objetos locales: **
** nuevoNodo,ultimo:NodoSimple */
1. nuevoNodo=new NodoSimple(dato, null)
2. Si esVacia()
3. cabeza=nuevoNodo
4. nuevoNodo.segSig(cabeza)
5. Sino
6. nuevoNodo.setSig(cabeza)
7. ultimo=cabeza
8. Mientras ultimo.getSig()≠cabeza
9. ultimo=ultimo.getSig()
10. ultimo.setSig(nuevoNodo)
11. cabeza=nuevoNodo
12. Return dato
ITPuebla 53
2.1. LISTAS
El TDA especificado para una lista simple es aplicable a una lista doble
y a una lista circular, ya que el TDA sólamente define qué operaciones se
pueden realizar con una lista, mientras que la implementación de ésta varı́a
de acuerdo al tipo de lista, como pueden verse los tres algoritmos diferentes
para implementar insertarCabeza en una lista simple (Algoritmo 11), en
una doble (Algoritmo 21) y en una circular (Algoritmo 22).
Con respecto a los recorridos, para una lista ligada doble, el recorrido
convencional, desde el primero hasta el último nodo, tiene un algoritmo
idéntico al de una lista simple. En una lista doble, también se pueden recorrer
los nodos desde el último hasta el primero, como en el algoritmo 23, donde
el primer ciclo (pasos 5 y 6) coloca aux en el último nodo, y el segundo ciclo
(pasos 7 a 9) aux va apuntando a los nodos desde el último hasta la cabeza,
haciendo referencia a la liga que apunta al nodo anterior, y en cada iteración
se van recolectando los datos en un vector. Los pasos 7 a 9 se ilustran en la
Figura 2.14
Algoritmo 23 recorrerUltimoPrimero():VectorObject
/* Recorre los elementos de la lista doble desde **
** el último hasta el primero, asignándolos a **
** un vector y lo retorna **
** Entradas: **
** ninguna **
** Salidas: **
** vec:Vector<Object> **
** Variables/Objetos locales: **
** aux:NodoSimple */
1. Si esVacia()
2. Return null
3. Sino
4. aux=cabeza
5. Mientras aux.getSig()≠null
6. aux=aux.getSig()
7. Mientras aux≠null
8. vec=vec.add(aux.getDato())
9. aux=aux.getAnt()
10. Return vec
ITPuebla 54
2.1. LISTAS
Figura 2.14: Recorrido de nodos en una lista doble, del útlimo al primero
ITPuebla 55
2.2. PILAS ESTÁTICAS Y DINÁMICAS
ITPuebla 56
2.2. PILAS ESTÁTICAS Y DINÁMICAS
Para eliminar elementos, se elimina primero el del tope. A partir del paso
6 de la Figura 2.16, se eliman componentes, comenzando con el último que
se introdujo, Compo 4.
ITPuebla 57
2.2. PILAS ESTÁTICAS Y DINÁMICAS
Los valores que puede tomar una pila y las operaciones que se pueden
realizar con ella se introducen formalmente mediante la definición de su
correspondiente TDA, como se ve enseguida [20]:
Definición de valores
int
Abstract typedef <algúnTipo> Pila
Definición de operaciones
Abstract <algúnTipo> push(Pila pil,<algúnTipo> componente)
Postcondition
en el tope de pil := componente
pil tiene un componente más
push := componente
Definición de operaciones
Abstract <algúnTipo> pop (Pila pil)
Precondition
pil no está vacı́a
Postcondition
pop := componente del tope de pil
pil tiene un componente menos
ITPuebla 58
2.2. PILAS ESTÁTICAS Y DINÁMICAS
Definición de operaciones
Abstract boolean esVacı́a (Pila pil)
Postcondition
esVacı́a := true si pil no tiene componentes
esVacı́a := false si pil tiene al menos un componente
Definición de operaciones
Abstract <algúnTipo>verTope (Pila pil)
Precontidion pil no es vacı́a
Postcondition
verTope := componente del tope de pil
En la Tabla 2.3 se ilustran las operaciones que hacen funcionar una pila.
En el paso 1, la pila está vacı́a, representada con corchetes vacı́os. En los
pasos 2 y 3, se insertan 2 elementos en la pila, los que se añaden en el tope,
que es el extremo derecho de los corchetes. En el paso 4, la operación pop
regresa el elemento del tope de la pila, es decir el del extremo derecho del
corchete, que es el valor 3, y lo elimina, quedando el elemento 5. En el paso
7, a diferencia de pop, la operación verTope regresa el elemento del tope
pero sin eliminarlo. En el paso 10 se verifica si la pila está vacı́a, dando
como resultado true, ya que es cierto que no tiene elementos.
ITPuebla 59
2.2. PILAS ESTÁTICAS Y DINÁMICAS
Ahora, una pila como TDA puede implementarse mediante una interfaz,
como se ve en el diagrama de clases de la Figura 2.17:
ITPuebla 60
2.2. PILAS ESTÁTICAS Y DINÁMICAS
Una pila puede implementarse con un vector, con lo que la pila es una
pila estática [3][18]. El diagrama de clases correspondiente a esta imple-
mentación se ve en la Figura 2.18.
ITPuebla 61
2.2. PILAS ESTÁTICAS Y DINÁMICAS
Algoritmo 24 PilaVector()
/* Constructor, inicializa/instancia variables/objetos **
** atributos de la clase, con valores por defecto **
** Entradas: **
** ninguna **
** Salidas: **
** ninguna */
1. tope=-1
2. vec=new Object[5]
ITPuebla 62
2.2. PILAS ESTÁTICAS Y DINÁMICAS
Algoritmo 25 PilaVector(longitud:int)
/* Constructor, inicializa/instancia variables/objetos **
** atributos de la clase, con valores de argumentos **
** Entradas: **
** longitud: int, tama~
no del vector **
** Salidas: **
** ninguna */
1. tope=-1
2. vec=new Object[longitud]
ITPuebla 63
2.2. PILAS ESTÁTICAS Y DINÁMICAS
1. Si esLlena()
2. Return null
3. Sino
4. tope++
5. vec[tope]=dato
6. Return dato
1. Si esVacia()
2. Return null
3. Sino
4. tope--
5. Return vec[tope+1]
ITPuebla 64
2.2. PILAS ESTÁTICAS Y DINÁMICAS
Tabla 2.4: Ejemplos de operaciones básicas con una pila como un vector
No. de Operación Salida Pila tope
paso (Entrada)
1 ninguna ninguna [ ][ ][ ][ ] (pila vacı́a) -1
2 esVacia() true [ ][ ][ ][ ] -1
3 pop() null [ ][ ][ ][ ] -1
4 push(3) 3 [3][ ][ ][ ] 0
5 push(5) 5 [3][5][ ][ ] 1
6 esLlena() false [3][5][ ][ ] 1
7 push(7) 7 [3][5][7][ ] 2
8 push(9) 9 [3][5][7][9] 3
9 push(11) null [3][5][7][9] 3
10 verTope() 9 [3][5][7][9] 3
11 esLlena() true [3][5][7][9] 3
12 pop() 9 [3][5][7][ ] 2
ITPuebla 65
2.2. PILAS ESTÁTICAS Y DINÁMICAS
Una pila implementada con una lista simple, como la de la Figura 2.19,
es una pila dinámica [3][18]. Del conjunto de nodos de la lista, se puede
tomar como tope de la pila a algún nodo de los extremos (al nodo cabeza o
al último nodo). Sin embargo, lo más eficiente es que el nodo cabeza sea el
tope de la pila; ası́, el método push de la pila se implementa insertando un
nuevo nodo en la cabeza de la lista, es decir con el método insertarCabeza
de la lista; pop de la pila se implementa eliminado el nodo cabeza con el
método eliminarCabeza de la lista; y verTope de la pila se implementa
accediendo al contenido del nodo cabeza con el método verCabeza de la
lista.
ITPuebla 66
2.2. PILAS ESTÁTICAS Y DINÁMICAS
Algoritmo 31 PilaListaSimple()
/* Constructor, inicializa/instancia variables/objetos **
** atributos de la clase, con valores por defecto **
** Entradas: **
** ninguna **
** Salidas: **
** ninguna */
1. pila=new ListaSimple()
ITPuebla 67
2.2. PILAS ESTÁTICAS Y DINÁMICAS
Algoritmo 32 PilaListaSimple(unaPila:ListaSimple)
/* Constructor, inicializa/instancia variables/objetos **
** atributos de la clase, con valores de argumentos **
** Entradas: **
** unaPila: ListaSimple **
** Salidas: **
** ninguna */
1. pila=unaPila
Algoritmo 33 esVacia():booleano
/* Verifica si la pila está vacı́a. Regresa true si **
** la pila está vacı́a, regresa false en caso contrario **
** Entradas: **
** ninguna **
** Salidas: **
** bandera: boolean */
1. Return pila.esVacia()
Algoritmo 34 push(dato:Object):Object
/* Inserta un dato en el tope de la pila. Retorna el **
** dato si inserción exitosa, retorna null en otro caso **
** Entradas: **
** dato: Object, dato a insertar **
** Salidas: **
** dato: Object, dato insertado */
1. Return pila.insertarCabeza(dato)
Algoritmo 35 pop():Object
/* Elimina un dato del tope de la pila. Retorna el **
** dato si la pila no es vacı́a, retorna null en caso **
** contrario **
** Entradas: **
** ninguna **
** Salidas: **
** dato: Object, dato eliminado del tope */
1. Return pila.eliminarCabeza()
ITPuebla 68
2.3. COLAS ESTÁTICAS Y DINÁMICAS
Algoritmo 36 verTope():Object
/* Regresa el dato del tope si pila no vacı́a, regresa **
** null en otro caso **
** Entradas: **
** ninguna **
** Salidas: **
** dato:Object */
1. Return pila.verCabeza()
Una cola o cola simple es una estructura de datos lineal (a cada com-
ponente le sucede y precede a lo más un componente), homogénea (cada
componente es del mismo tipo), y puede ser dinámica o estática, dependien-
do de su implementación (por ejemplo, si se implementa con un vector, es
estática).
ITPuebla 69
2.3. COLAS ESTÁTICAS Y DINÁMICAS
Definición de valores
int
Abstract typedef <algúnTipo> Cola
ITPuebla 70
2.3. COLAS ESTÁTICAS Y DINÁMICAS
Definición de operaciones
Abstract <algúnTipo> encolar(Cola col,
<algúnTipo> componente)
Postcondition
en el final de col := componente
col tiene un componente más
encolar := componente
Definición de operaciones
Abstract <algúnTipo> desencolar (Cola col)
Precondition
col no está vacı́a
Postcondition
desencolar := componente del frente de col
col tiene un componente menos
Definición de operaciones
Abstract boolean esVacı́a (Cola col)
Postcondition
esVacı́a := true si col no tiene componentes
esVacı́a := false si col tiene al menos un componente
Definición de operaciones
Abstract <algúnTipo>verFrente (Cola col)
Precondition
col no es vacı́a
Postcondition
verFrente := componente del frente de col
Definición de operaciones
Abstract <algúnTipo>verFinal (Cola col)
Precontidion col no es vacı́a
Postcondition
verFinal := componente del final de col
En este TDA se especifica que los valores que puede tomar una cola es el
de una colección de cierto número (int) de componentes de algún tipo. Las
operaciones del TDA se describen enseguida:
ITPuebla 71
2.3. COLAS ESTÁTICAS Y DINÁMICAS
En la Tabla 2.5 se ilustran las operaciones que hacen funcionar una cola.
En el paso 1, la cola está vacı́a, representada con corchetes vacı́os, siendo el
frente el extremo izquierdo de los corchetes, y el final el extremo derecho.
En los pasos 2, 3 y 4, se insertan 3 elementos en la cola, los que se añaden
en el final, que es el extremo derecho de los corchetes. En los pasos 5 y 6
se accede a los valores del frente y del final, respectivamente. El paso 7
elimina el componente del frente al desencolar el valor 5. La prueba de si
la cola es vacı́a en el paso 8, dá como resultado false. Desencolar elementos
de una cola vacı́a dá como resultado null, indicando que no hay elementos
qué desencolar, como en el paso 11; similarmente no pueden obtenerse los
valores del frente y final cuando la cola es vacı́a (pasos 13 y 14).
ITPuebla 72
2.3. COLAS ESTÁTICAS Y DINÁMICAS
Al igual que una pila, una cola puede implementarse con un vector,
dando como resultado una cola estática [18][3].
ITPuebla 73
2.3. COLAS ESTÁTICAS Y DINÁMICAS
Algoritmo 37 ColaVector()
/* Constructor, inicializa/instancia variables/objetos **
** atributos de la clase, con valores por defecto **
** Entradas: **
** ninguna **
** Salidas: **
** ninguna */
1. final=-1
2. vec=new Object[5]
ITPuebla 74
2.3. COLAS ESTÁTICAS Y DINÁMICAS
Algoritmo 38 ColaVector(longitud:int)
/* Constructor, inicializa/instancia variables/objetos **
** atributos de la clase, con valores de argumentos **
** Entradas: **
** longitud:int, tama~
no del vector **
** Salidas: **
** ninguna */
1. final=-1
2. vec=new Object[longitud]
Algoritmo 40 esLlena():booleano
/* Verifica si la cola está llena. Regresa true si la **
** cola está llena, regresa false en caso contrario **
** Entradas: **
** ninguna **
** Salidas: **
** un boolean */
1. Si final=vec.length-1
2. Return true
3. Sino
4. Return false
ITPuebla 75
2.3. COLAS ESTÁTICAS Y DINÁMICAS
Algoritmo 41 encolar(dato:Object):Object
/* Inserta un dato en el final de la cola. Retorna el **
** dato si inserción exitosa, retorna null en caso **
** contrario **
** Entradas: **
** dato:Object, dato a insertar **
** Salidas: **
** dato:Object, dato insertado */
1. Si esLlena()
2. Return null
3. Sino
4. final++
5. vec[final]=dato
6. Return dato
Algoritmo 42 desencolar():Object
/* Elimina un dato del frente de la cola (posición 0 del **
** vector). Retorna el dato si la cola no es vacı́a, **
** retorna null en caso contrario **
** Entradas: **
** ninguna **
** Salidas: **
** dato:Object, dato eliminado del frente **
** Variables/Objetos locales: **
** aux:Object */
1. Si esVacia()
2. Return null
3. Sino
4. aux = vec[0]
5. Para i=0,1,...,final-1
6. vec[i]=vec[i+1]
7. final--
8. Return aux
ITPuebla 76
2.3. COLAS ESTÁTICAS Y DINÁMICAS
Algoritmo 43 verFrente():Object
/* Regresa el dato del frente (posición 0 del **
** vector) si cola no vacı́a, regresa null en otro caso **
** Entradas: ninguna **
** Salidas: **
** dato: Object */
1. Si esVacia()
2. Return null
3. Sino
4. Return vec[0]
Algoritmo 44 verFinal():Object
/* Regresa el dato del final si cola no vacı́a, **
** regresa null en otro caso **
** Entradas: **
** ninguna **
** Salidas: **
** dato:Object */
1. Si esVacia()
2. Return null
3. Sino
4. Return vec[final]
En la Figura 2.24 se tiene una cola implementada con una lista simple,
y en la Figura 2.25 el diagrama de clases correspondiente (también puede
implementarse con una lista doble o una lista circular). Una cola implemen-
tada con una lista ligada es una cola dinámica [18][3]. En este caso, lo más
natural es que el nodo cabeza sea el frente de la cola, y el último nodo de
la lista sea el final de la cola. En la figura el final está indicado con lı́nea
punteada porque esa referencia no está definida en la clase ListaSimple.
ITPuebla 77
2.3. COLAS ESTÁTICAS Y DINÁMICAS
ITPuebla 78
2.3. COLAS ESTÁTICAS Y DINÁMICAS
Algoritmo 45 ColaListaSimple()
/* Constructor, inicializa/instancia variables/objetos **
** atributos de la clase, con valores por defecto **
** Entradas: **
** ninguna **
** Salidas: **
** ninguna */
1. cola=new ListaSimple()
Algoritmo 46 ColaListaSimple(longitud:int)
/* Constructor, inicializa/instancia variables/objetos **
** atributos de la clase, con valores de argumentos **
** Entradas: **
** unaCola:ListaSimple **
** Salidas: **
** ninguna */
1. cola=unaCola
ITPuebla 79
2.3. COLAS ESTÁTICAS Y DINÁMICAS
Algoritmo 48 encolar(dato:Object):Object
/* Inserta un dato en el final de la cola. **
** Retorna el dato **
** contrario **
** Entradas: **
** dato:Object, dato a insertar **
** Salidas: **
** dato:Object, dato insertado */
1. Return cola.insertarFinal(dato)
Algoritmo 49 desencolar():Object
/* Elimina un dato del frente de la cola. **
** Retorna el dato si la cola no es vacı́a, **
** retorna null en caso contrario **
** Entradas: **
** ninguna **
** Salidas: **
** dato:Object, dato eliminado del frente */
1. Return cola.eliminarCabeza()
Algoritmo 50 verFrente():Object
/* Regresa el dato del frente si cola no vacı́a, **
** regresa null en otro caso **
** Entradas: ninguna **
** Salidas: **
** dato: Object */
1. Return cola.verCabeza()
Algoritmo 51 verFinal():Object
/* Regresa el dato del final si cola no vacı́a, **
** regresa null en otro caso **
** Entradas: **
** ninguna **
** Salidas: **
** dato:Object */
1. Return cola.verFinal()
ITPuebla 80
2.3. COLAS ESTÁTICAS Y DINÁMICAS
Una cola circular es una cola implementada con un vector, donde los
ı́ndices frente y final siempre se incrementan al insertar o eliminar compo-
netes, a diferencia de una cola simple donde, de acuerdo a la implementación
presentada en la sección anterior, el ı́ndice frente está fijo en la posición
0 del vector y final se incrementa o decrementa, al insertar o eliminar
componetes [7][12][14].
frente=0 y final=4;
en la configuración de la derecha:
frente=4 y final=0.
En la Figura 2.28 se muestra una cola circular vacı́a y otra llena. Ambas
colas tienen la particularidad de que frente es mayor que final:
frente=4 >final=3.
ITPuebla 81
2.3. COLAS ESTÁTICAS Y DINÁMICAS
ITPuebla 82
2.3. COLAS ESTÁTICAS Y DINÁMICAS
ITPuebla 83
2.3. COLAS ESTÁTICAS Y DINÁMICAS
Figura 2.29: Interfaz Cola implementada con una cola circular con vector
Algoritmo 52 ColaCircularVector()
/* Constructor, inicializa/instancia variables/objetos **
** atributos de la clase, con valores por defecto **
** Entradas: **
** ninguna **
** Salidas: **
** ninguna */
1. frente=0
2. final=-1
3. vec=new Object[5]
ITPuebla 84
2.3. COLAS ESTÁTICAS Y DINÁMICAS
Algoritmo 53 ColaCircularVector(longitud:int)
/* Constructor, inicializa/instancia variables/objetos **
** atributos de la clase, con valores de argumentos **
** Entradas: **
** longitud:int, tama~
no del vector **
** Salidas: **
** ninguna */
1. frente=0
2. final=-1
3. vec=new Object[longitud]
Algoritmo 55 esLlena():booleano
/* Verifica si la cola circular está llena. Regresa **
** true si la cola está llena, regresa false en caso **
** contrario **
** Entradas: **
** ninguna **
** Salidas: **
** un boolean */
1. Si final<frente && vec[frente]!=null
2. Return true
3. Sino
4. Return false
ITPuebla 85
2.3. COLAS ESTÁTICAS Y DINÁMICAS
ITPuebla 86
2.3. COLAS ESTÁTICAS Y DINÁMICAS
Algoritmo 56 encolar(dato:Object):Object
/* Inserta un dato en el final de la cola circular. **
** Retorna el dato si inserción exitosa, **
** retorna null en caso contrario **
** Entradas: **
** dato:Object, dato a insertar **
** Salidas: **
** dato:Object, dato insertado */
1. Si esLlena()
2. Return null
3. Sino
4. final=(final+1) %vec.length()
5. vec[final]=dato
6. Return dato
Algoritmo 57 desencolar():Object
/* Elimina un dato del frente de la cola circular. **
** Retorna el dato si la cola no es vacı́a, **
** retorna null en caso contrario **
** Entradas: **
** ninguna **
** Salidas: **
** dato:Object, dato eliminado del frente **
** Variables/Objetos locales: **
** aux:Object */
1. Si esVacia()
2. Return null
3. Sino
4. aux = vec[frente]
5. vec[frente]=null
6. frente=(frente+1) %vec.length()
7. Return aux
ITPuebla 87
2.3. COLAS ESTÁTICAS Y DINÁMICAS
Algoritmo 58 verFrente():Object
/* Regresa el dato del frente si cola circular no es **
** vacı́a, regresa null en otro caso **
** Entradas: ninguna **
** Salidas: **
** dato: Object */
1. Si esVacia()
2. Return null
3. Sino
4. Return vec[frente]
Algoritmo 59 verFinal():Object
/* Regresa el dato del final si cola circular no es **
** vacı́a, regresa null en otro caso **
** Entradas: **
** ninguna **
** Salidas: **
** dato:Object */
1. Si esVacia()
2. Return null
3. Sino
4. Return vec[final]
ITPuebla 88
2.3. COLAS ESTÁTICAS Y DINÁMICAS
ITPuebla 89
2.3. COLAS ESTÁTICAS Y DINÁMICAS
Una cola doble también puede implementar la interfaz Cola con un vec-
tor, como se ve en la Figura 2.33. La clase ColaDobleVector mantiene los
mismos métodos de la interfaz, pero agrega comportamientos propios de
una cola doble y no de una cola en general: los métodos encolarFrente
y desencolarFinal. El método encolar corresponde a encolar un dato al
final, y el método desencolar coresponde a desencolar un dato del frente,
siguiendo la lógica de cualquier cola.
Figura 2.33: Interfaz Cola implementada con una cola doble con vector
ITPuebla 90
2.3. COLAS ESTÁTICAS Y DINÁMICAS
Algoritmo 60 ColaDobleVector()
/* Constructor, inicializa/instancia variables/objetos **
** atributos de la clase, con valores por defecto **
** Entradas: **
** ninguna **
** Salidas: **
** ninguna */
1. frente=2
2. final=1
3. vec=new Object[5]
Algoritmo 61 ColaCircularVector(longitud:int)
/* Constructor, inicializa/instancia variables/objetos **
** atributos de la clase, con valores de argumentos **
** Entradas: **
** longitud:int, tama~
no del vector **
** Salidas: **
** ninguna */
1. frente=longitud/2
2. final=frente-1
3. vec=new Object[longitud]
ITPuebla 91
2.3. COLAS ESTÁTICAS Y DINÁMICAS
Algoritmo 63 esLlena():booleano
/* Verifica si la cola doble está llena. Regresa **
** true si la cola está llena, regresa false en caso **
** contrario **
** Entradas: **
** ninguna **
** Salidas: **
** un boolean */
1. Si final=vec.length-1 && frente=0
2. Return true
3. Sino
4. Return false
ITPuebla 92
2.3. COLAS ESTÁTICAS Y DINÁMICAS
Algoritmo 64 encolarFrente(dato:Object):Object
/* Inserta un dato en el frente de la cola doble. **
** Retorna el dato si inserción exitosa, **
** retorna null en caso contrario **
** Entradas: **
** dato:Object, dato a insertar **
** Salidas: **
** dato:Object, dato insertado */
1. Si esLlena()
2. Return null
3. Sino
4. Si frente=0
5. Para i=final,final-1,...,frente
6. vec[i+1]=vec[i]
7. Sino
8. frente-- 9. vec[frente]=dato
10. Return dato
ITPuebla 93
2.3. COLAS ESTÁTICAS Y DINÁMICAS
Algoritmo 65 encolar(dato:Object):Object
/* Inserta un dato en el final de la cola doble. **
** Retorna el dato si inserción exitosa, **
** retorna null en caso contrario **
** Entradas: **
** dato:Object, dato a insertar **
** Salidas: **
** dato:Object, dato insertado */
1. Si esLlena()
2. Return null
3. Sino
4. Si final=vec.length-1
5. Para i=frente,frente+1,...,final
6. vec[i-1]=vec[i] 7. Sino
8. final++
9. vec[final]=dato
10. Return dato
Algoritmo 66 desencolar():Object
/* Elimina un dato del frente de la cola doble. **
** Retorna el dato si la cola no es vacı́a, **
** retorna null en caso contrario **
** Entradas: **
** ninguna **
** Salidas: **
** dato:Object, dato eliminado del frente **
** Variables/Objetos locales: **
** aux:Object */
1. Si esVacia()
2. Return null
3. Sino
4. aux = vec[frente]
5. frente++
6. Return aux
ITPuebla 94
2.3. COLAS ESTÁTICAS Y DINÁMICAS
Algoritmo 67 desencolarFinal():Object
/* Elimina un dato del final de la cola doble. **
** Retorna el dato si la cola no es vacı́a, **
** retorna null en caso contrario **
** Entradas: **
** ninguna **
** Salidas: **
** dato:Object, dato eliminado del frente **
** Variables/Objetos locales: **
** aux:Object */
1. Si esVacia()
2. Return null
3. Sino
4. aux = vec[final]
5. final--
6. Return aux
Algoritmo 68 verFrente():Object
/* Regresa el dato del frente si cola doble no es **
** vacı́a, regresa null en otro caso **
** Entradas: ninguna **
** Salidas: **
** dato: Object */
1. Si esVacia()
2. Return null
3. Sino
4. Return vec[frente]
ITPuebla 95
2.4. APLICACIONES
Algoritmo 69 verFinal():Object
/* Regresa el dato del final si cola doble no es **
** vacı́a, regresa null en otro caso **
** Entradas: **
** ninguna **
** Salidas: **
** dato:Object */
1. Si esVacia()
2. Return null
3. Sino
4. Return vec[final]
2.4. Aplicaciones
ITPuebla 96
2.4. APLICACIONES
Algoritmo 70 invierteVector(vec[n]):vec[n]
/* Invierte el contenido de un vector **
** Entradas: **
** vec:Object[n], vector de n elementos **
** Salidas: **
** vec:Object[n], vector de n elementos en **
** orden inverso **
** Variables/Objetos locales:
** vecaux:vector auxiliar de n cadenas */
1. Para i=0,1,...,n-1
2. vecaux[n-1-i]=vec[i]
3. Para i=0,1,...,n-1
4. vec[i]=vecaux[i]
5. Return vec
ITPuebla 97
2.4. APLICACIONES
Algoritmo 71 invierteVectorConPila(vec[n]):vec[n]
/* Invierte el contenido de un vector utilizando una pila **
** Entradas: **
** vec:Object[n], vector de n elementos **
** Salidas: **
** vec:Object[n], vector de n elementos **
** en orden inverso **
** Variables/Objetos locales: **
** pila:Pila */
1. Para i=0,1,...,n-1
2. pila.push(vec[i])
3. Para i=0,1,...,n-1
4. vec[i]=pila.pop()
5. Return vec
Figura 2.36: Diagrama de clases para invertir un vector utilizando una pila
ITPuebla 98
2.4. APLICACIONES
ITPuebla 99
2.4. APLICACIONES
ITPuebla 100
2.4. APLICACIONES
Algoritmo 72 verificaParen():boolean
/* Verifica que los paréntesis de una expresión estén **
** nivelados. Regresa true si los paréntesis están **
** nivelados, regresa false en caso contrario **
** Entradas: **
** exp:String, expresión de n sı́mbolos **
** Salidas: **
** bandera:boolean **
** Variables/Objetos locales: **
** pila:Pila */
1. Para i=0,1,...,n-1
2. Si exp[i]=’(’
3. pila.push(vec[i])
4. Sino
5. Si exp[i]=’)’
6. Si pila.pop()=null
7. Return false
8. Si pila.esVacia()
9. Return true
10. Sino
11. Return false
ITPuebla 101
2.4. APLICACIONES
Figura 2.41: Pila para convertir notación infija a posfija con un operador
ITPuebla 102
2.4. APLICACIONES
Figura 2.42: Pila para convertir notación infija a posfija con dos operadores
Figura 2.43: Notación infija a posfija con dos operadores en diferente orden
ITPuebla 103
2.4. APLICACIONES
ITPuebla 104
2.4. APLICACIONES
Figura 2.45: Diagrama de clases para el control de un cajero con una cola
1. Mientras !(colaCaj.esVacia())
2. despachandoA=colaCaj.desencolar()
3. Para i=1,2,...,despachandoA.getnumTran()
4. tiempo++
5. Print (’’Tiempo: ’’+tiempo)
6. Print (’’Despachando a: ’’+despachandoA.getNombre())
ITPuebla 106
Capı́tulo 3
Estructuras no lineales
3.1. Recursividad
107
3.1. RECURSIVIDAD
3.1.1. Definición
1! = 1, Caso base
n! = n(n − 1)! para n ≥ 2, Caso recursivo;
1! = 1,
2! = 2(1)! = (2)(1) = 2
3! = 3(2)! = (3)2! = (3)(2)1! = (3)(2)(1) = (3)(2)
4! = (4)(3)(2)(1) = (4)(3)(2)
5! = (5)(4)(3)(2)
...
n! = (n)(n − 1)(n − 2)...(2), para n ≥ 2;
ITPuebla 108
3.1. RECURSIVIDAD
Algoritmo 74 calculaFactorialIterativo(n:int):long
/* Calcula iterativamente el factorial de un número **
** Entradas: **
** n:int **
** Salidas: **
** fac:long */
1. Si n ≤ 1
2. fac=1
3. Sino
4. fac=1
5. Para i=n,n-1,n-2,...,2
6. fac=fac*i
7. Return fac
Algoritmo 75 calculaFactorialRecursivo(n:int):long
/* Calcula recursivamente el factorial de un número **
** Entradas: **
** n:int **
** Salidas: **
** fac:long */
1. Si n ≤ 1
2. fac=1
3. Sino
4. fac=n*calculaFactorialRecursivo(n-1)
5. Return fac
ITPuebla 109
3.1. RECURSIVIDAD
ITPuebla 110
3.1. RECURSIVIDAD
ITPuebla 111
3.1. RECURSIVIDAD
ITPuebla 112
3.1. RECURSIVIDAD
Algoritmo 76 buscaIterat(v:Object[n],n:int,dato:Object):boolean
ITPuebla 113
3.1. RECURSIVIDAD
Algoritmo 77 buscaRecur1(v:Object[n],i:int,n:int,dato:Object)
/* Busca recursivamente un dato en un vector **
** Entradas: **
** v:Object[n], vector de datos **
** i:int, ı́ndice al elemento i-ésimo, que funge **
** como primer elemento **
** n:int, longitud de v **
** dato:Object, dato a buscar **
** Salidas: **
** un booleano */
1. Si i=n-1 /* el elemento i es el único en el
vector, no hay resto */
2. Si v[i]=dato
3. Return true
4. Sino
5. Return false
6. Sino /* el elemento i es el primero del vector, y el
vector tiene un resto */
7. Si v[i]=dato
8. Return true
9. Sino
10. Return BuscaRecursivo1(v,i+1,n,dato) /* busca
recursivamente el dato en el resto
del vector */
ITPuebla 114
3.1. RECURSIVIDAD
Algoritmo 78 buscaRecur2(v:Object[],ini,fin,n:int,dato:Object)
/* Busca recursivamente un dato en un vector, utilizando **
** divide y vencerás **
** Entradas: **
** v:Object[n], vector de datos **
** ini:int, ı́ndice del elemento que funge como **
** primer elemento del subarreglo **
** fin:int, ı́ndice del elemento que funge como **
** último elemento del subarreglo **
** n:int, longitud de v **
** dato:Object, dato a buscar **
** Salidas: **
** un booleano */
ITPuebla 115
3.1. RECURSIVIDAD
ITPuebla 116
3.1. RECURSIVIDAD
ITPuebla 117
3.1. RECURSIVIDAD
Algoritmo 79 sumaRecursivoPrimeroResto(v:int[n],n:int,i:int)
/* Suma n números recursivamente utilizando la técnica **
** de procesar el primero y el resto de los números **
** Entradas: **
** v:int[n] **
** n: int **
** i: int **
** Salidas: **
** resul:int */
1. Si i=n
2. resul = v[i]
3. Sino
4. resul = v[i] + sumaRecursivoPrimeroResto(v,n,i+1)
5. Return resul
Algoritmo 80 sumaRecursivoDivideVenceras(v:int[n],n:int,i:int)
/* Suma n números recursivamente utilizando la técnica **
** de divide y vencerás **
** Entradas: **
** v:int[n] **
** ini: int **
** fin: int **
** Salidas: **
** resul:int */
1. resul = 0
2. Si ini=fin
3. resul = v[ini]
4. Sino
5. Si ini<fin
6. medio = (ini+fin)/2
7. resul = sumaRecursivoDivideVenceras(v,ini,medio) +
sumaRecursivoDivideVenceras(v,medio+1,fin)
8. Return resul
ITPuebla 118
3.2. GRAFOS
3.2. Grafos
y los lados:
Figura 3.5: Grafo utilizado para representar una red de estados de la región
oriente e la República Mexicana
ITPuebla 119
3.2. GRAFOS
caso, todos sus nodos. No lineal, porque a cada componente le puede pre-
ceder o suceder uno o más componentes. Dinámica, porque el número de
componentes puede variar en tiempo de ejecución [20][5][9][7][12].
ITPuebla 120
3.2. GRAFOS
A(i, j) = A(j, i) = {
1, si los nodos i, j son adyascentes,
0, en otro caso.
ITPuebla 121
3.2. GRAFOS
ITPuebla 122
3.2. GRAFOS
I(i, j) = {
1, si el nodo i incide en el lado j,
0, en otro caso.
ITPuebla 123
3.2. GRAFOS
Figura 3.8: Inserción de nodos (b) y lados (c) en un grafo, con matrices de
adyascencia A e incidencia I
ITPuebla 124
3.2. GRAFOS
Figura 3.9: Eliminación de nodos (a) y lados (b) en un grafo, con matrices
de adyascencia A e incidencia I
ITPuebla 125
3.2. GRAFOS
ITPuebla 126
3.2. GRAFOS
Definición de valores
int int
Abstract typedef <Nodos> <Lados>
int×int int×int
<MatInc> , <MatAdy> Grafo
Definición de operaciones
Abstract <Nodos> insertarNodo(<Nodos> nuevoNodo,
Grafo G)
Precondition
NuevoNodo ∉ <Nodos>
Postcondition
MatAdy incrementa un renglón y una columna,
que se etiquetan con nodo
MatInc incrementa un renglón,
que se etiquetan con nodo
el grafo G tiene un componente más
<Nodos> := <Nodos> U {nuevoNodo}
insertarNodo := nodo
Definición de operaciones
Abstract <Lados> insertarLado(<Lados< nuevoLado,
<Nodos> n1, <Nodos> n2, Grafo G)
Precondition
n1,n2 ∈<Nodos>
nuevoLado ∉<Lados>
Postcondition
MatAdy[n1][n2]:=1
MatAdy[n2][n1]:=1
MadInc[n1][nuevoLado]:=1
MadInc[n2][nuevoLado]:=1
el grafo G tiene un lado más
<Lados> := <Lados> U {nuevoLado}
insertarLado := nuevoLado
ITPuebla 127
3.2. GRAFOS
Definición de operaciones
Abstract <Nodos> eliminarNodo(<Nodos> nodo,
Grafo G)
Precondition
nodo ∈ <Nodos>
Postcondition
MatAdy decrementa un renglón y una columna,
etiquetada con nodo
MatInc decrementa un renglón,
etiquetada con nodo
el grafo G tiene un componente menos
<Nodos> := <Nodos> - {nodo}
<Lados> := <Lados> - {lados incidentes en nodo}
eliminarNodo := nodo
Definición de operaciones
Abstract <Lados> eliminarLado(<Lados> lado, Grafo G)
Precondition
lado ∈<Lados>
lado incide en n1 y n2
n1,n2 ∈ <Nodos>
Postcondition
MatAdy[n1][n2]:=0
MatAdy[n2][n1]:=0
MatInc decrementa una columna,
etiquetada con lado
el grafo G tiene un lado menos
<Lados> := <Lados> −{lado}
eliminarLado := lado
ITPuebla 128
3.2. GRAFOS
Definición de operaciones
int
Abstract <Nodos> recorrerAncho(<Nodos> nodoFuente,
Grafo G)
Precondition
nodoFuente ∈<Nodos>
Postcondition
recorrido := {visita todos los nodos de manera que,
estando en un nodo, enseguida se visitan sus
nodos adyascentes }
recorrerAncho := recorrido
Definición de operaciones
int
Abstract <Nodos> recorrerLargo(<Nodos< nodoFuente,
Grafo G)
Precondition
nodoFuente ∈<Nodos>
Postcondition
recorrido := {visita todos los nodos de manera que,
estando en un nodo, enseguida se visita
sólamente uno de sus nodos adyascentes, quedando
pendiente el resto }
recorrerLargo := recorrido
ITPuebla 129
3.2. GRAFOS
ITPuebla 130
3.2. GRAFOS
ITPuebla 131
3.2. GRAFOS
Los métodos del diagrma de la Figura 3.13 se implementan con los algo-
ritmos del 81 al 87.
Algoritmo 81 GrafoNoDirigido()
/* Constructor, inicializa/instancia variables/objetos **
** atributos de la clase, con valores por defecto **
** Entradas: **
** ninguna **
** Salidas: **
** ninguna */
1. nodos = new Vector<String>()
2. lados = new Vector<String>()
3. matAdy = new int[0][0]
4. matInc = new int[0][0]
ITPuebla 132
3.2. GRAFOS
Algoritmo 82 insertarNodo(nodo:String):String
/* Inserta un nuevo nodo en el grafo no dirigido. **
** Retorna el nuevo nodo si la inserción fue exitosa, **
** retorna null en caso de que el nodo ya exista en el **
** grafo **
** Entradas: **
** nodo:String, nuevo nodo **
** Salidas: **
** nodo:String, nuevo nodo insertado **
** Variables/Objetos locales: **
** matAux:int[][] */
1. Si nodo∈nodos
2. Return null
3. Sino
4. nodos.add(nodo)
5. /* agrega un renglón y una columna a matAdy */
6. matAux=new int[matAdy.length+1][matAdy.length+1]
7. /* copia matAdy en matAux */
8. Para i=0,1,...,matAdy.length-1
9. Para j=0,1,...,matAdy.length-1
10. matAux[i][j] = matAdy[i][j]
11. /* actualiza matAdy */
12. matAdy = matAux
13. /* agrega un renglón a matInc */
14. matAux=new int[matInc.length+1][matInc[0].length]
15. /* copia matInc en matAux */
16. Para i=0,1,...,matInc.length-1
17. Para j=0,1,...,matInc[0].length-1
18. matAux[i][j] = matInc[i][j]
19. /* actualiza matInc */
20. matInc = matAux
21. Return nodo
ITPuebla 133
3.2. GRAFOS
Algoritmo 83 insertarLado(lado,n1,n2:String):String
/* Inserta un nuevo lado en el grafo no dirigido. **
** Retorna el nuevo lado si la inserción fue exitosa, **
** retorna null en caso de que n1 o n2 no existan en **
** el grafo, o lado ya exista en el grafo **
** Entradas: **
** lado:String, nuevo lado **
** n1:String, nodo incidente en lado **
** n2:String, nodo incidente en lado **
** Salidas: **
** lado:String, nuevo lado insertado **
** Variables/Objetos locales: **
** matAux:int[][] */
1. Si (n1∈nodos)&&(n2∈nodos)&&(lado∉lados)
2. lados.add(lado)
3. ren=nodos.get(n1)
4. col=nodos.get(n2)
5. matAdy[ren][col]=1
6. matAdy[col][ren]=1
7. /* agrega una columna a matInc */
8. matAux=new int[matInc.length][matInc[0].length+1]
9. /* copia matInc en matAux */
10. Para i=0,1,...,matInc.length-1
11. Para j=0,1,...,matInc[0].length-1
12. matAux[i][j] = matInc[i][j]
13. /* actualiza matInc */
14. matInc = matAux
15. /* marca incidencias del lado con dos nodos */
16. matInc[ren][matInc[0].length-1]=1
17. matInc[col][matInc[0].length-1]=1
18. Return lado
19. Sino
20. Return null
ITPuebla 134
3.2. GRAFOS
Algoritmo 84 eliminarNodo(nodo:String):String
/* Elimina un nodo del grafo no dirigido. Retorna el **
** nodo si la eliminación fue exitosa, retorna null si **
** el nodo no existe en el grafo **
** Entradas: **
** nodo:String, nodo a eliminar **
** Salidas: **
** nodo:String, nodo eliminado **
** Variables/Objetos locales: **
** matAux:int[][] */
1. Si nodo∉nodos
2. Return null
3. Sino
4. k=nodos.get(nodo)
5. /* elimina un renglón y una columna a matAdy */
6. matAux=new int[matAdy.length-1][matAdy.length-1]
7. /* copia matAdy en matAux, excepto el k-ésimo
8. renglón y columna */
9. ii=0
10. Para i=0,1,...,matAdy.length-1
11. Si i≠k
12. jj=0
13. Para j=0,1,...,matAdy.length-1
14. Si j≠k
15. matAux[ii][jj] = matAdy[i][j]
16. jj=jj+1
17. ii=ii+1
18. matAdy = matAux /* actualiza matAdy */
19. /* elimina un renglón a matInc */
20. matAux=new int[matInc.length-1][matAdy.length]
21. /* copia matInc en matAux, excepto el renglón k
22. ii=0
23. Para i=0,1,...,matAdy.length-1
24. Si i≠k
25. Para j=0,1,...,matAdy.length-1
26. matAux[ii][j] = matAdy[i][j]
27. ii=ii+1
28. matInc = matAux /* actualiza matInc */
29. nodos.remove(nodo)
30. Return nodo
ITPuebla 135
3.2. GRAFOS
Algoritmo 85 eliminarLado(lado:String):String
/* Elimina un lado en el grafo no dirigido. Retorna el **
** lado si la eliminación fue exitosa, retorna null si **
** el lado no existe en el grafo **
** Entradas: **
** lado:String, lado a eliminar **
** Salidas: **
** lado:String, lado eliminado **
** Variables/Objetos locales: **
** matAux:int[][] */
1. Si lado∈lados
2. ren=lados.get(n1)
3. col=nodos.get(n2)
4. matAdy[ren][col]=1
5. matAdy[col][ren]=1
6. k=lados.get(lado)
7. /* elimina una columna a matInc */
8. matAux=new int[matInc.length][matInc[0].length-1]
9. /* copia matInc en matAux, excepto columna k-ésima
10. columna */
11. Para i=0,1,...,matInc.length-1
12. jj=0
13. Para j=0,1,...,matInc.length-1
14. Si j≠k
15. matAux[i][jj] = matAdy[i][j]
16. jj=jj+1
17. /* actualiza matInc */
18. matInc = matAux
19. lados.remove(lado)
20. Return lado
21. Sino
22. Return null
ITPuebla 136
3.2. GRAFOS
Algoritmo 86 recorrerAncho(nodoFuente:String):Vector<String>
/* Recorre a lo ancho un grafo, a partir de un nodo **
** fuente. Retorna el recorrido resultante si el nodo **
** fuente existe, retorna null en otro caso. **
** Entradas: **
** nodoFuente:String, nodo de partida **
** Salidas: **
** recorrido:Vector<String>, recorrido a lo **
** ancho **
** Variables/Objetos locales: **
** cola:ColaVector<String>, auxiliar para **
** recorrido **
** visitados:Vector<String>, banderas de nodos **
** visitados **
** nod:String, nodo que se está visitando */
1. Si nodoFuente∈nodos
2. recorrido=new Vector<String>()
3. k=nodos.get(nodoFuente)
4. cola=new ColaVector<String>()
5. cola.encolar(nodoFuente)
6. visitados=new Vector<String>()
7. /* copia los nodos en visitados */
8. Para i=0,1,...,nodos.length()
9. visitados.add(nodos.get(i))
10. Mientras !cola.esVacia()
11. nod = cola.desencolar()
12. Si !visitados.exists(nod)
13. recorrido.add(nod)
14. visitado.delete(nod)
15. /* encola los nodos adyascentes a nod */
16. Para i=0,1,...,matAdy.length-1
17. Si matAdy[k][i]==1
18. Si !visitados.exists(nodos.get(i))
19. cola.encolar(nodos.get(i))
20. Return recorrido
21. Sino
22. Return null
ITPuebla 137
3.2. GRAFOS
Una cola donde se van almacenando los nodos que queda pendiente
por recorrerse. La forma en que funciona una cola (el primer elemento
en insertarse es el primero en eliminarse), permite que los nodos del
grafo se recorran visitando primero todos los adyascentes de un nodo
dado. En el algoritmo se utiliza un objeto de la clase ColaVector.
ITPuebla 138
3.2. GRAFOS
ITPuebla 139
3.2. GRAFOS
ITPuebla 140
3.2. GRAFOS
ITPuebla 141
3.2. GRAFOS
Algoritmo 87 recorrerLargo(nodoFuente:String):Vector<String>
/* Recorre a lo largo un grafo, a partir de un nodo **
** fuente. Retorna el recorrido resultante si el nodo **
** fuente existe, retorna null en otro caso. **
** Entradas: **
** nodoFuente:String, nodo de partida **
** Salidas: **
** recorrido:Vector<String>, recorrido a lo **
** largo **
** Variables/Objetos locales: **
** pila:PilaVector<String>, auxiliar para **
** recorrido **
** visitados:Vector<String>, banderas de nodos **
** visitados **
** nod:String, nodo que se está visitando */
1. Si nodoFuente∈nodos
2. recorrido=new Vector<String>()
3. k=nodos.get(nodoFuente)
4. pila=new PilaVector<String>()
5. pila.push(nodoFuente)
6. visitados=new Vector<String>()
7. Para i=0,1,...,nodos.length()
8. visitados.add(nodos.get(i))
9. Mientras !pila.esVacia()
10. nod = pila.pop()
11. Si !visitados.exists(nod)
12. recorrido.add(nod)
13. visitado.delete(nod)
14. /* empila los nodos adyascentes a nod */
15. Para i=0,1,...,matAdy.length-1
16. Si matAdy[k][i]==1
17. pila.push(nodos.get(i))
18. Return recorrido
19. Sino
20. Return null
ITPuebla 142
3.2. GRAFOS
3.2.3. Aplicaciones
Una aplicación tı́pica de los grafos es el cálculo del camino más corto o
más barato entre dos nodos en un grafo dirigido ponderado. Para ello, se
define [15][19][8]:
Figura 3.18: Grafo dirigido para representar el orden en que Batman debe
ponerse la ropa [17]
ITPuebla 143
3.2. GRAFOS
ITPuebla 144
3.2. GRAFOS
Figura 3.20: Grafo dirigido y ponderado, con tres posibles caminos entre
Hidalgo y Guerrero, siendo el más barato o más corto el de 566 Km.
Uno de los algoritmos que permite calcular el camino más barato o corto
entre un nodo fuente y el resto de los nodos en un grafo ponderado dirigido,
es el Algoritmo de Dijkstra[19][11]. Este algoritmo hace uso de la matriz
de pesos del grafo, pero también mantiene un vector de costos, cada elemento
ITPuebla 145
3.2. GRAFOS
del vector corresponde a un nodo y representa el costo más barato del camino
que va desde el nodo fuente hasta el nodo. También mantiene un vector de
banderas, denominado vector de marcas, donde se indica por cada nodo si se
ha considerado como nodo de costo mı́nimo o no. El algoritmo de Dijkstra
funciona como en el ejemplo de la Figura 3.21, donde se identifican:
ITPuebla 146
3.2. GRAFOS
ITPuebla 147
3.2. GRAFOS
Algoritmo 88 dijkstra(nodoFuente:String,nodoDestino:String):int
3.3. Árboles
En la Figura 3.22 (a) se tiene un grafo no dirigido que representa una rela-
ción de amistad entre los nodos, pero tiene varios ciclos, por ejemplo (Jobim,
De Moraes, Viglietti, Buarque, Veloso, Jobim) o (Rodrı́guez, Cos-
ta, Serrat, Rodrı́guez), por lo que no es un árbol. En (b) se tiene un grafo
no conexo, entonces no es un árbol. Para representar las personas que son
jefas de otras, en (c) se utiliza un grafo dirigido, que también es conexo y no
tiene ciclos, además se indentifica a De Moraes como raı́z porque tiene gra-
do interno cero, las hojas son Serrat, Buarque, Gilberto, Rodrı́guez,
Chávez porque tienen grado externo cero, y Jobim, Viglietti, Veloso,
Costa son los nodos interiores porque tienen grado interno uno; con esto,
este grafo es un árbol, que puede redibujarse como en (d), colocando los
nodos por niveles o renglones, desde la raı́z hasta las hojas.
ITPuebla 149
3.3. ÁRBOLES
Figura 3.22: Ejemplos de grafos que no son árboles (a) y (b), y que sı́ lo son
(c) y (d)
En la Figura 3.22 (d), De Moraes es la raı́z del árbol y sus hijos son Jobim
y Viglietti; los hijos de Viglietti son Gilberto, Costa y Chávez; etc.,
las hojas no tienen hijos. El padre de Serrat y Veloso es Jobim; el padre
de Buarque es Veloso; etc., la raı́z no tiene padre. Serrat y Veloso son
hermanos. Los descendientes de Viglietti son Gilberto, Costa, Chávez y
Rodrı́guez. Los ancestros de Buarque son Veloso, Jobim y De Moraes.
ITPuebla 150
3.3. ÁRBOLES
ITPuebla 151
3.3. ÁRBOLES
ITPuebla 152
3.3. ÁRBOLES
Figura 3.25: Árboles de aridad tres (a), y aridad dos (árboles binarios) (b)
ITPuebla 153
3.3. ÁRBOLES
ITPuebla 154
3.3. ÁRBOLES
Los árboles de búsqueda se representan con nodos. Cada nodo tiene tres
campos: el que contiene la información que se requiere almacenar, el que
apunta al hijo izquierdo y el que apunta al hijo derecho, como en la Figura
3.28.
ITPuebla 155
3.3. ÁRBOLES
ITPuebla 156
3.3. ÁRBOLES
ITPuebla 157
3.3. ÁRBOLES
ITPuebla 158
3.3. ÁRBOLES
Figura 3.32: Eliminar un nodo hoja (Costa) y un nodo con un sólo hijo
(Serrat) en un árbol de búsqueda
ITPuebla 159
3.3. ÁRBOLES
Figura 3.33: Eliminar un nodo con dos hijos (Veloso) en un árbol de búsque-
da
ITPuebla 160
3.3. ÁRBOLES
ITPuebla 161
3.3. ÁRBOLES
Definición de valores
Abstract typedef <Nodo> ÁrbolBús
Definición de operaciones
Abstract boolean esVacı́o (ÁrbolBús raı́z)
Postcondition
esVacio := true si raı́z no apunta a ningún nodo
esVacio := false si raı́z apunta a un nodo
ITPuebla 162
3.3. ÁRBOLES
Definición de operaciones
Abstract <Nodo> buscarNodo(<AlgúnTipo> dato,
ÁrbolBús raı́z)
Postcondition
Si raı́z = null
buscarNodo := null
Si raı́z ≠ null
apunta aux a raı́z
Si aux.info = dato
buscarNodo := aux Si aux.info <dato
buscarNodo:= buscarNodo(dato,raı́z.derecho)
Si aux.info >dato
buscarNodo := buscarNodo(dato,raı́z.izquierdo)
Definición de operaciones
Abstract <AlgúnTipo> insertarNodo
(<AlgúnTipo> nuevoDato, ÁrbolBús raı́z)
Postcondition
crea nuevoNodo para almacenar nuevoDato
Si raı́z = null
raź := nuevoNodo
insertarNodo := nuevoDato
Sino
aux := buscarNodo(nuevoDato, raı́z)
Si aux <nuevoDato
aux.derecho := nuevoNodo
Sino
aux.izquierdo := nuevoNodo
insertarNodo := nuevoDato
ITPuebla 163
3.3. ÁRBOLES
Definición de operaciones
Abstract <AlgúnTipo> eliminarNodo(<AlgúnTipo> dato,
ÁrbolBús raı́z)
Postcondition
Si raı́z = null
eliminarNodo := nuevoDato
Sino
aux := buscarNodo(dato, raı́z)
Si aux es hoja
apuntar el padre de aux a null
eliminarNodo := nuevoDato
Si aux tiene un solo hijo
apuntar al padre de aux a su hijo
eliminarNodo := nuevoDato
Si aux tiene dos hijos
buscar predecesor de aux
aux.info = predecesor.info
eliminarNodo := eliminarNodo(aux.info,aux)
Definición de operaciones
Abstract Vector recorrerEnorden(ÁrbolBús raı́z)
Postcondition
Si raı́z = null
recorrerEnorden := null
Sino
recorrido := recorrerEnorden(raı́z.izquierdo)
recorrido := recorrido.add(raı́z.info)
recorrido := recorrido.add(
recorrerEnorden(raı́z.derecho))
recorrerEnorden := recorrido
ITPuebla 164
3.3. ÁRBOLES
Definición de operaciones
Abstract Vector recorrerPreorden(ÁrbolBús raı́z)
Postcondition
Si raı́z = null
recorrerPreorden := null
Sino
recorrido := raı́z.info
recorrido := recorrido.add(recorrerPreorden(
raı́z.izquierdo))
recorrido := recorrido.add(recorrerPreorden(
raı́z.derecho))
recorrerPreorden := recorrido
Definición de operaciones
Abstract Vector recorrerPostorden(ÁrbolBús raı́z)
Postcondition
Si raı́z = null
recorrerPostorden := null
Sino
recorrido := recorrerPostorden(raı́z.izquierdo)
recorrido := recorrido.add(recorrerPostorden(
raı́z.derecho))
recorrido := recorrido.add(raı́z.info)
recorrerPostorden := recorrido
ITPuebla 165
3.3. ÁRBOLES
Algoritmo 89 ArbolBusqueda()
/* Constructor, inicializa/instancia variables/objetos **
** atributos de la clase, con valores por defecto **
** Entradas: **
** ninguna **
** Salidas: **
** ninguna */
1. raiz = null
ITPuebla 166
3.3. ÁRBOLES
Algoritmo 90 esVacio():boolean
/* Verifica si el árbol está vacı́o o no **
** Entradas: **
** ninguna **
** Salidas: **
** bandera:boolean */
1. Si raiz = null
2. Return true
3. Sino
4. Return false
Algoritmo 91 buscarNodo(dato:String,raiz,padreRaiz:Nodo):Vector<Nodo>
ITPuebla 167
3.3. ÁRBOLES
Algoritmo 92 insertarNodo(dato:String):String
/* Inserta un dato ordenadamente en el árbol. Retorna **
** el dato si no está en el árbol. Retorna null si **
** el dato ya está en el árbol **
** Entradas: **
** dato:String, dato a insertar **
** Salidas: **
** dato:String */
1. nuevoNodo = new Nodo(dato,null,null)
2. Si raiz=null
3. raiz=nuevoNodo
4. Return dato
5. Sino
6. apuntadores=buscarNodo(dato,raiz,null)
7. aux=apuntadores.get(0)
8. padreAux=apuntadores.get(1)
9. Si aux=null /* dato no está en el árbol */
10. Si padreAux.getDato()<dato
11. padreAux.setDer(nuevoNodo)
12. Sino
13. padreAux.setIzq(nuevoNodo)
14. Return dato
15. Sino
16. Return null
ITPuebla 168
3.3. ÁRBOLES
Algoritmo 93 eliminarNodo(dato:String):String
/* Elimina un dato del árbol. Retorna null si el dato **
** no está en el árbol. Retorna el dato si se eliminó **
** Entradas: **
** dato:String, dato a eliminar **
** Salidas: **
** dato:String */
1. Si raiz=null
2. Return null
3. Sino
4. apuntadores=buscarNodo(dato,raiz,null)
5. aux=apuntadores.get(0)
6. padreAux=apuntadores.get(1)
7. Si aux=null /* dato no está en el árbol */
8. Return null
9. Sino
10. /* el nodo el hoja */
11. Si aux.getIzq()=null && aux.getDer()=null
12. Si aux=raiz raiz=null
13. Sino eliminarHoja(padreAux,aux)
14. /* el nodo tiene un sólo hijo izquierdo */
15. Si aux.getIzq()≠null && aux.getDer()=null
16. Si aux=raiz raiz=raiz.getIzq()
17. Sino eliminarHijoIzq(padreAux,aux)
18. /* el nodo tiene un sólo hijo derecho */
19. Si aux.getDer()≠null && aux.getIzq()=null
20. Si aux=raiz raiz=raiz.getDer()
21. Sino eliminarHijoDer(padreAux,aux)
22. /* el nodo tiene dos hijos */
23. Si aux.getDer()≠null && aux.getIzq()≠null
24. apuntadores=buscaPredecesor(aux.getIzq())
25. pred=apuntadores.get(0)
26. padrePred=apuntadores.get(1)
27. aux.setDato(pred.getDato())
28. Si padrePred=null
29. aux.setIzq(null)
30. Sino
31. eliminarHijoIzq(padrePred,pred)
32. Return dato
ITPuebla 169
3.3. ÁRBOLES
Algoritmo 94 eliminarHoja(padreAux,aux:Nodo):void
/* Elimina un nodo hoja de un árbol de búsqueda **
** Entradas: **
** aux:Nodo, nodo a eliminar **
** padreAux:Nodo, padre de aux **
** Salidas: **
** ninguna */
1. /* nodo es hijo izquierdo de su padre */
2. Si padreAux.getIzq()=aux
3. padreAux.setIzq(null)
4. /* nodo es hijo derecho de su padre */
5. Si padreAux.getDer()=aux
6. padreAux.setDer(null)
Algoritmo 95 eliminarHijoIzq(dato:String):String
/* Elimina un nodo que tiene un sólo hijo izquierdo **
** de un árbol de búsqueda **
** Entradas: **
** aux:Nodo, nodo a eliminar **
** padreAux:Nodo, padre de aux **
** Salidas: **
** Ninguna */
1. /* nodo es hijo izquierdo de su padre */
2. Si padreAux.getIzq()=aux
3. padreAux.setIzq(aux.getIzq())
4. /* nodo es hijo derecho de su padre */
5. Si padreAux.getDer()=aux
6. padreAux.setDer(aux.getIzq())
7. Return dato
ITPuebla 170
3.3. ÁRBOLES
Algoritmo 96 eliminarHijoDer(dato:String):String
/* Elimina un nodo que tiene un sólo hijo derecho **
** de un árbol de búsqueda **
** Entradas: **
** aux:Nodo, nodo a eliminar **
** padreAux:Nodo, padre de aux **
** Salidas: **
** ninguna */
1. /* nodo es hijo izquierdo de su padre */
2. Si padreAux.getIzq()=aux
3. padreAux.setIzq(aux.getDer())
4. /* nodo es hijo derecho de su padre */
5. Si padreAux.getDer()=aux
6. padreAux.setDer(aux.getDer())
Algoritmo 97 buscaPredecesor(aux:Nodo):String
/* Elimina un nodo que tiene un sólo hijo derecho **
** de un árbol de búsqueda **
** Entradas: **
** aux:Nodo, nodo a eliminar **
** padreAux:Nodo, padre de aux **
** Salidas: **
** ninguna */
1. padreAux=null
2. Mientras aux.getDer() ≠ null
3. padreAux=aux
4. aux=aux.getDer()
5. apuntadores.add(aux)
6. apuntadores.add(padreAux)
7. Return apuntadores
ITPuebla 171
3.3. ÁRBOLES
Algoritmo 98 recorrerEnorden(raiz:Nodo):Vector<String>
/* Recorre recursivamente en orden un árbol binario **
** Entradas: **
** raiz:Nodo, **
** Salidas: **
** recorrido:Vector<String> */
1. recorrido=new Vector<String>()
2. Si raiz ≠ null
3. recorrido.add(recorrerEnorden(raiz.getIzq()))
4. recorrido.add(raiz.getDato())
5. recorrido.add(recorrerEnorden(raiz.getDer()))
6. Return recorrido
Algoritmo 99 recorrerPreorden(raiz:Nodo):Vector<String>
/* Recorre recursivamente en preorden un árbol binario **
** Entradas: **
** raiz:Nodo, **
** Salidas: **
** recorrido:Vector<String> */
1. recorrido=new Vector<String>()
2. Si raiz ≠ null
3. recorrido.add(raiz.getDato())
4. recorrido.add(recorrerEnorden(raiz.getIzq()))
5. recorrido.add(recorrerEnorden(raiz.getDer()))
6. Return recorrido
ITPuebla 172
3.3. ÁRBOLES
1. recorrido=new Vector<String>()
2. Si raiz ≠ null
3. recorrido.add(recorrerEnorden(raiz.getIzq()))
4. recorrido.add(recorrerEnorden(raiz.getDer()))
5. recorrido.add(raiz.getDato())
6. Return recorrido
3.3.4. Aplicaciones
ITPuebla 173
3.3. ÁRBOLES
ITPuebla 174
3.3. ÁRBOLES
ITPuebla 175
Capı́tulo 4
Métodos de ordenamiento y
búsqueda
176
4.1. MÉTODOS DE ORDENAMIENTO
ITPuebla 177
4.1. MÉTODOS DE ORDENAMIENTO
Tabla 4.2: Archivo de los alumnos del Tec–Puebla, con registros ordenados
de acuerdo al número de control.
Número de Control Nombre Fecha de Nacimiento
09220001 Ana López Ramı́rez 02/04/1989
09220005 Marı́a Luna Dı́az 30/11/1990
09220008 Pedro Cruz Pérez 19/12/1989
09220010 Julio Ruı́z Blanco 17/08/1988
09220013 Nadia Luz Morales 28/09/1987
09220021 José Oropeza Bueno 21/08/1991
Tabla 4.3: Archivo de los alumnos del Tec–Puebla, con registros ordenados
de acuerdo al apellido.
Número de Control Nombre Fecha de Nacimiento
09220008 Pedro Cruz Pérez 19/12/1989
09220001 Ana López Ramı́rez 02/04/1989
09220005 Marı́a Luna Dı́az 30/11/1990
09220013 Nadia Luz Morales 28/09/1987
09220021 José Oropeza Bueno 21/08/1991
09220010 Julio Ruı́z Blanco 17/08/1988
ITPuebla 178
4.1. MÉTODOS DE ORDENAMIENTO
Inserción Directa
ITPuebla 179
4.1. MÉTODOS DE ORDENAMIENTO
0 1 2 3 4
A Ana Mary Pedro Carmen Juan
0 1 2 3 4
A Ana Mary Carmen Pedro Juan
0 1 2 3 4
A Ana Carmen Mary Pedro Juan
0 1 2 3 4
A Ana Carmen Mary Juan Pedro
ITPuebla 180
4.1. MÉTODOS DE ORDENAMIENTO
0 1 2 3 4
A Mary Ana Pedro Carmen Juan
0 1 2 3 4
A Pedro Ana Mary Carmen Juan
ITPuebla 181
4.1. MÉTODOS DE ORDENAMIENTO
cambios en el arreglo.
Pone a Juan en su lugar:
comparando A[4] con A[4 − paso] = A[2] y cambiando el contenido
del arreglo:
0 1 2 3 4
A Pedro Ana Juan Carmen Mary
0 1 2 3 4
A Juan Ana Pedro Carmen Mary
Hasta aquı́ se tiene un primer ciclo de ordenamiento, en donde los datos han
quedado ordenados cada dos componentes de A (porque paso = 2), es decir
A[0] < A[2] < A[4] (Juan < Pedro < Mary) y A[1] < A[3] (Ana < Carmen).
A continuación la Inserción Directa Generalizada decrementa el tamaño de
paso con paso = paso/2 = 1, con lo que el método se comporta como el de
la Inserción Directa, de aquı́ su generalización, ya que la Inserción Directa
Generalizada se convierte en la Inserción Directa cuando el tamaño de paso
es 1. Entonces:
Pone a Ana en su lugar:
comparando A[1] con A[0] y cambiando el contenido del arreglo:
0 1 2 3 4
A Ana Juan Pedro Carmen Mary
ITPuebla 182
4.1. MÉTODOS DE ORDENAMIENTO
0 1 2 3 4
A Ana Juan Carmen Pedro Mary
0 1 2 3 4
A Ana Carmen Juan Pedro Mary
0 1 2 3 4
A Ana Carmen Juan Mary Pedro
ITPuebla 183
4.1. MÉTODOS DE ORDENAMIENTO
Ordenamiento de la Burbuja
0 1 2 3 4
A Mary Ana Pedro Carmen Juan
ITPuebla 184
4.1. MÉTODOS DE ORDENAMIENTO
0 1 2 3 4
A Ana Mary Pedro Carmen Juan
compara A[1] con A[2] y no es necesario cambiar los datos del arreglo,
compara A[2] con A[3] y cambiando el contenido del arreglo:
0 1 2 3 4
A Ana Mary Carmen Pedro Juan
0 1 2 3 4
A Ana Mary Carmen Juan Pedro
con esto, el método ha dejado al mayor de los datos (Pedro) en el último com-
ponente del arreglo, con lo que el dato queda ordenado. El método continúa
poniendo la siguiente cadena alfabéticamente más grande en el penúltimo
componente del arreglo, para ello:
compara A[0] con A[1] y no es necesario cambiar los datos del arreglo,
compara A[1] con A[2] y cambia el contenido del arreglo:
0 1 2 3 4
A Ana Carmen Mary Juan Pedro
0 1 2 3 4
A Ana Carmen Juan Mary Pedro
ITPuebla 185
4.1. MÉTODOS DE ORDENAMIENTO
Ordenamiento Rápido
ITPuebla 186
4.1. MÉTODOS DE ORDENAMIENTO
0 1 2 3 4 5
A Ana Juan Carmen Mary Sara Pedro
ITPuebla 187
4.1. MÉTODOS DE ORDENAMIENTO
ITPuebla 188
4.1. MÉTODOS DE ORDENAMIENTO
ITPuebla 189
4.1. MÉTODOS DE ORDENAMIENTO
ITPuebla 190
4.1. MÉTODOS DE ORDENAMIENTO
Por otra parte, haciendo referencia a la Figura 4.4, en el nivel 1 del árbol
se concatenan seis parejas de conjuntos de datos: en la primera pareja los
ITPuebla 191
4.1. MÉTODOS DE ORDENAMIENTO
ITPuebla 192
4.1. MÉTODOS DE ORDENAMIENTO
ITPuebla 193
4.1. MÉTODOS DE ORDENAMIENTO
ITPuebla 194
4.1. MÉTODOS DE ORDENAMIENTO
de datos de los ı́ndices [i2 , ..., f2 ], para lo cual se utiliza un arreglo auxiliar
AU X para ir construyendo el conjunto de datos ordenados que resultan de
la concatenación de otros dos conjuntos de datos ordenados.
Selección Directa
0 1 2 3 4
A Mary Ana Pedro Carmen Juan
0 1 2 3 4
A Ana Mary Pedro Carmen Juan
compara A[0] con A[2], con A[3] y con A[4], sin necesidad de cambiar
los datos del arreglo,
pues Ana es el menor de todos.
El método vuelve a realizar el mismo procedimiento ahora colocando el
siguiente dato menor del conjunto en la posición 1 del arreglo, para esto:
compara A[1] con A[2] y no hay cambios,
compara A[1] con A[3] y cambia los datos del arreglo como sigue:
ITPuebla 195
4.1. MÉTODOS DE ORDENAMIENTO
0 1 2 3 4
A Ana Carmen Pedro Mary Juan
0 1 2 3 4
A Ana Carmen Mary Pedro Juan
0 1 2 3 4
A Ana Carmen Juan Pedro Mary
0 1 2 3 4
A Ana Carmen Juan Mary Pedro
ITPuebla 196
4.1. MÉTODOS DE ORDENAMIENTO
ITPuebla 197
4.1. MÉTODOS DE ORDENAMIENTO
0 1 2 3 4 5 6 7 8 9 10 11 12 13
A a e c k m f r n s p k h w
donde, por ejemplo, el nodo a de la posición k=0 del arreglo tiene su hijo
izquierdo e almacenado en la posición 2k + 1 = 2 × 0 + 1 = 1 y su hijo derecho
c almacenado en la posición 2k + 2 = 2 × 0 + 2 = 2; en otro ejemplo, el nodo f
que está almacenado en la posición k=5 del arreglo, tiene su hijo izquierdo
k en la posición 2k + 1 = 2 × 5 + 1 = 11 y su hijo derecho h en la posición
2k + 2 = 2 × 5 + 2 = 12. La forma en que se almacenan los nodos de un
montı́culo en un arreglo corresponde al recorrido por niveles o a lo ancho
del montı́culo.
0 1 2 3 4 5
A Mary Ana Sara Pedro Juan Carmen
ITPuebla 198
4.1. MÉTODOS DE ORDENAMIENTO
ITPuebla 199
4.1. MÉTODOS DE ORDENAMIENTO
Este proceso vuelve a repetirse con la nueva raı́z Carmen, que es el se-
gundo elemento ordenado del arreglo original. En la Figura 4.8(d), la nueva
raı́z es Mary, que se intercambia con el menor de sus hijos, Juan, quedando
el montı́culo de la Figura 4.8(e). Notar que el arreglo A se va llenando con
las raı́ces que se van eliminando del montı́culo, las cuales están ordenadas
alfabéticamente de manera ascendente.
ITPuebla 200
4.1. MÉTODOS DE ORDENAMIENTO
siendo la nueva raı́z Sara. Por último se elimina Sara (Figura 4.8(h)) ,
quedando el montı́culo vacı́o y el arreglo A con los datos ordenados.
ITPuebla 201
4.1. MÉTODOS DE ORDENAMIENTO
ITPuebla 202
4.1. MÉTODOS DE ORDENAMIENTO
ITPuebla 203
4.2. MÉTODOS DE BÚSQUEDA
Búsqueda Secuencial.
Búsqueda Binaria.
ITPuebla 204
4.2. MÉTODOS DE BÚSQUEDA
0 1 2 3 4 5
A Ana Carmen Juan Mary Pedro Sara
y que se desea buscar el dato Mary. Para ello, se utiliza un ı́ndice que empiece
indizando a la posición 0 del arreglo, y se hace una comparación de si el
dato buscado Mary está en la posición 0, como no es ası́, el ı́ndice avanza a
la posición 1 y vuelve a comparar. Este procedimiento continúa hasta que
el ı́ndice apunte a la posiciı́n 3 y al comparar Mary, el datos buscado, con
el contenido en esa posición, verifica que son iguales, por lo que se puede
concluir que el dato buscado sı́ está en el arreglo.
ITPuebla 205
4.2. MÉTODOS DE BÚSQUEDA
ITPuebla 206
4.2. MÉTODOS DE BÚSQUEDA
ITPuebla 207
4.3. MEDICIÓN TEÓRICA DEL TIEMPO DE EJECUCIÓN DE LOS
ALGORITMOS DE ORDENAMIENTO Y BÚSQUEDA
Algoritmo 112 busquedaBinaria(A:Object[N],dato:Object):int
/* Busca un dato en un arreglo ordenado de objetos, **
** utilizando el método de la búsqueda binaria **
** Entradas: **
** A:Object[N], vector ordenado **
** dato:Object, dato a buscar en el vector **
** Salidas: **
** i:int, posición del dato en el vector */
1. i=0
2. f=N-1
3. m=(i+f)/2
4. encontrado=Falso
5. Mientras (i≤f)&&(encontrado=Falso)
6. Si A[m]=dato
7. encontrado=Verdadero
8. Sino
9. Si A[m]<dato
10. i=m+1
11. Sino
12. f=m-1
13. m=(i+f)/2
14. Si encontrado=Verdadero
15. Return m
16. Sino
17. Return -1
ITPuebla 208
4.3. MEDICIÓN TEÓRICA DEL TIEMPO DE EJECUCIÓN DE LOS
ALGORITMOS DE ORDENAMIENTO Y BÚSQUEDA
5–6, que conforman el bloque de sentencias que se ejecutan dentro del ciclo
Mientras del paso 4, este bloque tiene un tiempo de ejecución de:
TbloqueM ientras (N ) = 1,
Ahora, el bloque de sentencias del ciclo Para, es decir, de los pasos 2–7, tiene
un tiempo de ejecución de:
por lo que la sentencia iterativa Para del paso 1 tiene el siguiente tiempo de
ejecución y orden de complejidad:
TInserciónDirecta (N ) = = O(N ).
2
N N 2
−
2 2
ITPuebla 209
4.3. MEDICIÓN TEÓRICA DEL TIEMPO DE EJECUCIÓN DE LOS
ALGORITMOS DE ORDENAMIENTO Y BÚSQUEDA
Algoritmo 113 insercionDirecta(A:Object[N]):Object[N]
/* Tiempos de ejecución del método de la inserción directa **
** Entradas: **
** A:Object[N], vector a ordenar **
** Salidas: **
** A:Object[N], vector ordenado */
TP ara (N ) = O(N )
2
1. Para k=1,2,...,N-1
2. dato=A[k] T2 (N ) = 1
3. i=k-1 T3 (N ) = 1
4. Mientras (i≥0) && (dato<A[i]) TM ientras (N ) = k
5. A[i+1]=A[i] T5 (N ) = 1
6. i=i-1 T6 (N ) = 1
7. A[i+1]=dato T7 (N ) = 1
Ordenamiento de la Burbuja
con lo que:
TP ara2 (N ) = ∑ TSi...Entonces (N ) = ∑ 1 = N − 1 − k.
N −1−k N −1−k
j=0 j=0
ITPuebla 210
4.3. MEDICIÓN TEÓRICA DEL TIEMPO DE EJECUCIÓN DE LOS
ALGORITMOS DE ORDENAMIENTO Y BÚSQUEDA
se tiene que:
TP ara1 (N ) = ∑ TP ara2 (N ) = ∑ (N − 1 − k) = ∑ N − ∑ 1 − ∑ k =
N −1 N −1 N −1 N −1 N −1
= N (N − 1) − (N − 1) − (N − 1) = (N − 1)(N − 1 − ) =
N N
2 2
= (N − 1)( − 1) =
N
2
+ 1 = O(N ),
2
N N 2
= −N −
2 2
por lo que el algoritmo del Ordenamiento de la Burbuja es de orden cuadráti-
co, de igual forma que la Inserción Directa, es decir:
TBurbuja (N ) = − N + 1 = O(N ).
2
N 3 2
2 2
Ordenamiento Rápido
ITPuebla 211
4.3. MEDICIÓN TEÓRICA DEL TIEMPO DE EJECUCIÓN DE LOS
ALGORITMOS DE ORDENAMIENTO Y BÚSQUEDA
Como se ha visto en la Figura 4.2, el Ordenamiento Rápido ordena un
componente llamado pivote del arreglo de datos, colocando los datos meno-
res que el pivote a su izquierda y los mayores que el pivote a su derecha,
formando ası́ un árbol binario al ir ordenando con el mismo método ambos
conjuntos. Un caso ideal (el mejor de los casos) sucede cuando los pivotes
quedan ordenados exactamente a la mitad del arreglo de datos en manipula-
ción, pues ası́ se va formando un árbol binario equilibrado, que tiene altura
mı́nima de ⌊log2 N ⌋ con N nodos. El peor caso sucede cuando los pivotes
quedan ordenados en uno de los extremos del arreglo de datos en manipu-
lación, quedando el resto de los datos a su izquierda o bien a su derecha,
formando un árbol binario totalmente desequilibrado (es decir, formando
una lista ligada, que es una estructura lineal), que tiene altura máxima de
N con N nodos.
Además de la altura del árbol binario que se va formando, hay que con-
siderar que el número de comparaciones que se hacen en cada nivel del árbol
es, en términos de orden superior, del orden de N con N datos. Esto puede
deducirse como sigue, considerando que el árbol binario es equilibrado:
− 1 = O (2 ) = O(N )
N −1 N
2
2 2
datos.
En el tercer nivel del árbol se comparan cuatro pivotes con cuatro
subconjuntos (los izquierdos y los derechos de los pivotes del nivel
anterior) de:
N −1
2
−1
−1
2
datos cada uno, es decir, en total se comparan:
N −1
4( − 1) = O (4 ) = O(N )
2
−1 N
2 4
ITPuebla 212
4.3. MEDICIÓN TEÓRICA DEL TIEMPO DE EJECUCIÓN DE LOS
ALGORITMOS DE ORDENAMIENTO Y BÚSQUEDA
datos.
ITPuebla 213
4.3. MEDICIÓN TEÓRICA DEL TIEMPO DE EJECUCIÓN DE LOS
ALGORITMOS DE ORDENAMIENTO Y BÚSQUEDA
Un análisis similiar puede hacerse para el Ordenamiento por Concatena-
ción, ya que construye un árbol binario equilibrado, como se ve en la Figura
4.4, y en cada nivel del árbol se hace un número de comparaciones del orden
de O(N ) para construir el tercer conjunto ordenado de datos, a partir de dos
conjuntos ordenados de datos. De esta forma se puede concluir que el orden
de complejidad del Ordenamiento por Concatenación es:
ITPuebla 214
4.3. MEDICIÓN TEÓRICA DEL TIEMPO DE EJECUCIÓN DE LOS
ALGORITMOS DE ORDENAMIENTO Y BÚSQUEDA
Algoritmo 116 insertarEnMontı́culo(A:Object[N]):Object[N]
/* Tiempos de ejecución de la inserción de los objetos **
** de un vector en un montı́culo presentado esquemáticamente **
** Entradas: **
** A:Object[N], vector a insertar **
** Salidas: **
** mont:Object[N], montı́culo */
Búsqueda Secuencial
ITPuebla 215
4.3. MEDICIÓN TEÓRICA DEL TIEMPO DE EJECUCIÓN DE LOS
ALGORITMOS DE ORDENAMIENTO Y BÚSQUEDA
Algoritmo 117 busquedaSecuencial(A:Object[N],dato:Object):int
/* Tiempos de ejecución del método de la búsqueda **
** secuencial **
** Entradas: **
** A:Object[N], vector ordenado **
** dato:Object, dato a buscar en el vector **
** Salidas: **
** i:int, posición del dato en el vector */
1. encontrado=Falso T1 (N ) = 1
2. i=0 T2 (N ) = 1
3. Mientras (i<N)&&(encontrado=Falso) T3 (N ) = O(N )
4. Si A[i]=dato
5. encontrado=Verdadero
6. Sino
7. i=i+1
8. Si encontrado=Verdadero T8 (N ) = 1
9. Return i
10.Sino
11. Return -1
Búsqueda Binaria
ITPuebla 216
4.3. MEDICIÓN TEÓRICA DEL TIEMPO DE EJECUCIÓN DE LOS
ALGORITMOS DE ORDENAMIENTO Y BÚSQUEDA
Algoritmo 118 busquedaBinaria(A:Object[N],dato:Object):int
/* Tiempos de ejecución del método de la búsqueda **
** binaria **
** Entradas: **
** A:Object[N], vector ordenado **
** dato:Object, dato a buscar en el vector **
** Salidas: **
** i:int, posición del dato en el vector */
1. i=0 T1 (N ) = 1
2. f=N-1 T2 (N ) = 1
3. m=(i+f)/2 T3 (N ) = 1
4. encontrado=Falso T4 (N ) = 1
5. Mientras (i≤f)&&(encontrado=Falso)
6. Si A[m]=dato T6 (N ) = 1
7. encontrado=Verdadero
8. Sino
9. Si A[m]<dato T9 (N ) = 1
10. i=m+1
11. Sino
12. f=m-1
13. m=(i+f)/2 T13 (N ) = 1
14. Si encontrado=Verdadero T14 (N ) = 1
15. Return m
16. Sino
17. Return -1
ITPuebla 217
4.4. RECUPERACIÓN DE DATOS
ITPuebla 218
4.4. RECUPERACIÓN DE DATOS
ITPuebla 219
4.4. RECUPERACIÓN DE DATOS
ITPuebla 220
4.4. RECUPERACIÓN DE DATOS
ITPuebla 221
4.4. RECUPERACIÓN DE DATOS
ITPuebla 222
4.4. RECUPERACIÓN DE DATOS
ITPuebla 223
4.4. RECUPERACIÓN DE DATOS
ITPuebla 224
4.4. RECUPERACIÓN DE DATOS
ITPuebla 225
4.4. RECUPERACIÓN DE DATOS
ITPuebla 226
4.4. RECUPERACIÓN DE DATOS
ITPuebla 227
4.4. RECUPERACIÓN DE DATOS
ITPuebla 228
4.4. RECUPERACIÓN DE DATOS
Figura 4.15: Esquema de la ejecución del Algoritmo 122 que inserta un nuevo
registro en la posición lógica 3 de un Archivo Secuencial. En los cı́rculos se
indican los números de paso del algoritmo.
ITPuebla 229
4.4. RECUPERACIÓN DE DATOS
ITPuebla 230
4.4. RECUPERACIÓN DE DATOS
Figura 4.16: Esquema de la ejecución del Algoritmo 123 que elimina el primer
registro de un Archivo Secuencial. En los cı́rculos se indican los números de
paso del algoritmo.
ITPuebla 231
4.4. RECUPERACIÓN DE DATOS
Figura 4.17: Esquema de la ejecución del Algoritmo 124 que elimina el último
registro de un Archivo Secuencial.
ITPuebla 232
4.4. RECUPERACIÓN DE DATOS
ITPuebla 233
4.4. RECUPERACIÓN DE DATOS
Consultas.
Para consultar o ver el contenido de un registro de un Archivo Secuen-
cial, se requiere de un proceso de búsqueda del registro en el archivo.
El proceso de búsqueda ya se ha empleado en las operaciones de AL-
TAS, BAJAS y MODIFICACIONES en los casos en que se necesita
localizar en el archivo un registro especı́fico. Con el Algoritmo 126 se
localiza el registro de una dirección lógica concreta en el archivo y se
lee para su consulta. Este algoritmo puede modificarse para localizar
un registro con una clave especı́fica.
ITPuebla 234
4.4. RECUPERACIÓN DE DATOS
ITPuebla 235
4.4. RECUPERACIÓN DE DATOS
ITPuebla 236
4.4. RECUPERACIÓN DE DATOS
ITPuebla 237
4.4. RECUPERACIÓN DE DATOS
1. i=0
2. encontrado=Falso
3. Mientras (i<tablaDir.length())&&(encontrado=Falso)
4. Si tablaDir[i].getClave()=clave
5. encontrado=Verdadero
6. Sino
7. i=i+1
8. Si encontrado
9. Return tablaDir[i].getDirRel()
10. Sino
11. Return -1 /* clave no encontrada */
ITPuebla 238
4.4. RECUPERACIÓN DE DATOS
1. dirRel = tablaDir.buscar(clave)
2. Si dirRel=-1 /* la clave no está en la tablaDir */
3. j=tablaDir.getNumeroClaves()-1
4. parar=Falso
5. Mientras (j≥0)&&(!parar)
6. Si tablaDir[j].getClave()>clave
7. tablaDir[j+1].setClave(tablaDir[j].getClave()
8. tablaDir[j+1].setDirRel(tablaDir[j].getDirRel()
9. j=j-1
10. Sino
11. tablaDir[j+1].setClave(clave)
12. tablaDir[j+1].setDirRel(dirRelativa)
13. parar=Verdadero
14. Return dirRel
ITPuebla 239
4.4. RECUPERACIÓN DE DATOS
ITPuebla 240
4.4. RECUPERACIÓN DE DATOS
ITPuebla 241
4.4. RECUPERACIÓN DE DATOS
Las bajas de registros se consideran bajas lógicas, por lo que las di-
recciones relativas que se van liberando tras las bajas se almacenan
en una lista ligada llamada ListaLibres. A través de ListaLibres se
controlan las posiciones del archivo que van quedando disponibles para
nuevas altas de registros.
Las bajas de registros se consideran bajas lógicas, por lo que las di-
recciones relativas que se van liberando tras las bajas se almacenan
en una lista ligada llamada ListaLibres. A través de ListaLibres se
controlan las posiciones del archivo que van quedando disponibles para
nuevas altas de registros.
ITPuebla 242
4.4. RECUPERACIÓN DE DATOS
ITPuebla 243
4.4. RECUPERACIÓN DE DATOS
ITPuebla 244
4.4. RECUPERACIÓN DE DATOS
ITPuebla 245
4.4. RECUPERACIÓN DE DATOS
ITPuebla 246
4.4. RECUPERACIÓN DE DATOS
f (clave) = dirRel,
ITPuebla 247
4.4. RECUPERACIÓN DE DATOS
ITPuebla 248
4.4. RECUPERACIÓN DE DATOS
ITPuebla 249
4.4. RECUPERACIÓN DE DATOS
Figura 4.23: Ejemplo de uso de una Tabla de Acceso Directo como estructura
de datos auxiliar para el acceso a un Archivo Directo.
ITPuebla 250
4.4. RECUPERACIÓN DE DATOS
ITPuebla 251
4.4. RECUPERACIÓN DE DATOS
debe ser, a lo más, igual que 0.7, es decir, TD no debe llenarse con claves
más allá del 70 % de su capacidad [16].
f (c) = c mod M,
ITPuebla 252
4.4. RECUPERACIÓN DE DATOS
Figura 4.24: Ejemplo de uso de una Tabla Hash como estructura de datos
auxiliar para el acceso a un Archivo Directo utilizando el Método de la
División
ITPuebla 253
4.4. RECUPERACIÓN DE DATOS
ITPuebla 254
4.4. RECUPERACIÓN DE DATOS
Las operaciones para buscar, insertar y eliminar una clave en una TD,
con el método de la dispersión abierta, están en los algoritmos 138, 139
y 140, correspondientemente, donde FuncionHash(clave) es un llamado a
un algoritmo que puede aplicar algún método de dispersión, como el de la
división o la multiplicación.
ITPuebla 255
4.4. RECUPERACIÓN DE DATOS
ITPuebla 256
4.4. RECUPERACIÓN DE DATOS
ITPuebla 257
4.4. RECUPERACIÓN DE DATOS
ITPuebla 258
4.4. RECUPERACIÓN DE DATOS
Cada nodo de cualquier lista ligada de TD, tiene tres campos: una clave
dispersada, la dirección relativa asociada a la clave, y un apuntador al
siguiente nodo.
Las bajas de los registros se consideran lógicas, por lo que las direccio-
nes relativas que se liberan se almacenan en una lista ligada llamada
ListaLibres, a través de la cual se controlan las posiciones del archi-
vo que van quedando disponibles para nuevas altas de registros. Esto
también significa que, fı́sicamente, los registros eliminados permanecen
en el Archivo Directo, sin embargo podrán ser reutilizados al dar de
alta nuevos registros.
ITPuebla 259
4.4. RECUPERACIÓN DE DATOS
ITPuebla 260
4.4. RECUPERACIÓN DE DATOS
ITPuebla 261
4.4. RECUPERACIÓN DE DATOS
ITPuebla 262
4.4. RECUPERACIÓN DE DATOS
1. dirRel=TD.buscarClaveTD(clave)
2. Si dirRel≠-1 /* clave encontrada */
3. archivo.abrir()
4. archivo.seek(dirRel)
5. reg=archivo.leerRegistro()
6. archivo.cerrar()
7. Return reg /* consulta exitosa */
8. Sino
9. Return null /* consulta no exitosa */
ITPuebla 263
4.4. RECUPERACIÓN DE DATOS
ITPuebla 264
Índice alfabético
265
ÍNDICE ALFABÉTICO
ITPuebla 266
ÍNDICE ALFABÉTICO
ITPuebla 267
ÍNDICE ALFABÉTICO
ITPuebla 268
ÍNDICE ALFABÉTICO
Ejemplos, 23
Suma de matrices, 25
Suma de vectores, 24
Regla de la suma, 21
Regla del producto, 21
Tipo de dato
Clasificación, 2
Definición, 2
Estructurado, 2
Clasificación, 3
Dinámico, 5
Ejemplos, 2
Estático, 5
Heterogéneo, 4
Homogéneo, 4
Lineal, 4
No lineal, 4
Operaciones básicas, 2
Simple, 2
Tipo de dato abstracto (TDA)
Definición, 7
Esquema general, 8
ITPuebla 269
Bibliografı́a
[4] Sara Baase and Allen Van Gelder. Algoritmos computacionales. Intro-
ducción al análisis y diseño. Pearson Educación, 2002.
[6] Bruce Eckel. Thinking in Java (4th Edition). Prentice Hall, 2006.
[7] Michael T. Goodrich and Roberto Tamassia. Data Structures and Al-
gorithms in JAVA. John Wiley & Sons, Inc., 2006.
270
BIBLIOGRAFÍA
[12] Elliot B. Koffman and Paul A.T. Wolfgang. Estructura de datos con
C++. Objetos, abstracciones y diseño. McGraw Hill, 2008.
[15] R.C.T. Lee, S.S. Tseng, R.C. Chang, and Y.T. Tsai. Introducción al
diseño y análisis de algoritmos. Un enfoque estratégico. McGraw Hill,
2007.
ITPuebla 271