Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Proyecto Final
Todos los Parciales
Programas
1
Contents
1 Primer Parcial 4
1.1 Repaso Apuntadores . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.1.1 Descripción de Programa . . . . . . . . . . . . . . . . . . 4
1.1.2 Código en C . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.1.3 Entradas . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
1.1.4 Salidas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
1.1.5 Link del Programa . . . . . . . . . . . . . . . . . . . . . . 10
1.2 Pilas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
1.2.1 Descripción de Programa . . . . . . . . . . . . . . . . . . 11
1.2.2 Código en C . . . . . . . . . . . . . . . . . . . . . . . . . 12
1.2.3 Entradas . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
1.2.4 Salidas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
1.2.5 Link del Programa . . . . . . . . . . . . . . . . . . . . . . 18
2 Segundo Parcial 19
2.1 Listas Simplemente Enlazadas . . . . . . . . . . . . . . . . . . . . 19
2.1.1 Descripción de Programa . . . . . . . . . . . . . . . . . . 19
2.1.2 Código en C . . . . . . . . . . . . . . . . . . . . . . . . . 20
2.1.3 Entradas . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
2.1.4 Salidas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
2.1.5 Link del Programa . . . . . . . . . . . . . . . . . . . . . . 35
2.2 Listas Doblemente Enlazadas . . . . . . . . . . . . . . . . . . . . 36
2.2.1 Descripción de Programa . . . . . . . . . . . . . . . . . . 36
2.2.2 Código en C . . . . . . . . . . . . . . . . . . . . . . . . . 38
2.2.3 Entradas . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
2.2.4 Salidas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
2.2.5 Link del Programa . . . . . . . . . . . . . . . . . . . . . . 78
2.3 Tablas Hash . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
2.3.1 Descripción de Programa . . . . . . . . . . . . . . . . . . 79
2.3.2 Código en C . . . . . . . . . . . . . . . . . . . . . . . . . 81
2
3.3 MST: Minimum Spanning Tree . . . . . . . . . . . . . . . . . . . 144
3.4 Algoritmo de Kruskal . . . . . . . . . . . . . . . . . . . . . . . . 146
3.4.1 Código . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148
3.5 Algoritmo de Prim . . . . . . . . . . . . . . . . . . . . . . . . . . 149
3
1 Primer Parcial
1.1 Repaso Apuntadores
Un Apuntador es una variable que contiene la dirección de otra variable y se
representa por medio de los operadores de dirección (&) e indirección (*). El
primero proporciona la dirección de un objeto y el segundo permite el acceso al
objeto del cual se tiene la dirección.
4
1.1.2 Código en C
5 //Estructura de la Matriz
6 typedef struct{
7 char ID_user[7];
8 char dia;
9 char mes;
10 char movimiento;
11 float Rho;
12
13 }Experimento;
14
15 /*Zona de protipos*/
16
35 Experimento **Ex1 = 0;
36 unsigned X, Y;
37
38 Ex1 = CreaMatriz(X,Y);
39
40 Experimento **AP1 = 0;
5
41 AP1 = (Experimento**)malloc(4*sizeof(Experimento*));
42
43
46 AP1[i] = (Experimento*)malloc(4*sizeof(Experimento));
47 }
48
49 CapturaMatriz(AP1);
50
51
52 return 0;
53 }
54
57 scanf("%u", &TAMX);
58
59 TAMY = TAMX;
60
61 Experimento **Ex = 0;
62 int i;
63
64 Ex = (Experimento**)malloc(TAMX*sizeof(Experimento));
65
66
77 return Ex;
78
79 }
80
83 int i, j;
84
6
91 scanf("%s %u %u %c %f", ap1[i][j].ID_user, &ap1[i][j].dia,
&ap1[i][j].mes, &ap1[i][j].movimiento, &ap1[i][j].Rho);
92 printf("\n%s %u %u %c %f", ap1[i][j].ID_user, ap1[i][j].dia,
ap1[i][j].mes, ap1[i][j].movimiento, ap1[i][j].Rho);
93 printf("\n");
94 }
95
96 printf("\n");
97 }
98
99
109 }
110
127
132
7
139 printf("\n");
140
141 }
142
143 printf("\n");
144 }
145
146 return;
147
148 }
1.1.3 Entradas
8
1.1.4 Salidas
9
Matriz de la Base de Datos de los Experimentos:
10
1.2 Pilas
Una pila es una lista ordenada o estructura de datos que permite almacenar y
recuperar datos, el modo de acceso a sus elementos es de tipo LIFO (del inglés
Last In, First Out, último en entrar, primero en salir).
Para el manejo de los datos cuenta con dos operaciones básicas: apilar (push),
que coloca un objeto en la pila, y su operación inversa, retirar (o desapilar,
pop), que retira el último elemento apilado.
11
1.2.2 Código en C
11 int size;
12 int top;
13 char **stacki;
14
15 } Table;
16
17
18
19 /*Zona de prototipos*/
20
12
42 Salidas: Regresa 1 si se pudo argregar el nuevo elemento*/
43 int Pushi(Table *N, char L[5]);
44
57 int main() {
58
59
60 //VARIABLES
61 char Seleccion, Carta;
62 char Libro[5];
63 Table A, B, C;
64 int sA, sB, sC;
65 int D = 0;
66
70 IniStacki(&A, sA);
71 IniStacki(&B, sB);
72 IniStacki(&C, sC);
73
74
75 while (D != 1){
76
77 scanf("%c\t", &Seleccion);
78 //printf("La Mesa es: %c\n", Seleccion);
79
80
81 switch (Seleccion) {
82
83 case ’A’:
84
85 scanf("%c\t", &Carta);
86 //printf("Carta: %c\n", Carta);
87
88
89 switch (Carta) {
13
90
91 case ’N’:
92
93 scanf("%s\n", &Libro);
94 //printf("Libro: %s\n", Libro);
95 Pushi(&A, Libro);
96
97 case ’R’:
98
99 Popi(&A);
100
101 break;
102 default:
103 break;
104 }
105
106
107 break;
108
109
110
116
125 break;
126
129 Popi(&B);
130
131 break;
132 default:
133 break;
134 }
135
136
137 break;
138
139
14
140
146
155
156 break;
157
160 Popi(&C);
161
162
163 break;
164 default:
165 break;
166 }
167
168
169 break;
170
171
172 default:
173 break;
174 }
175
180 D++;
181 }
182
183
184 }
185
15
190 ImprimeWeas(C, ’C’);
191
192 return 0;
193 }
194
195
199 int i;
200
201 N->size = S;
202 N->top = -1;
203
213 return;
214
215 }
216
221 return 1;
222
223 }
224
227 }
228
233 return 1;
234
235 }
236
239 }
16
240
247 }
248
251 return 1;
252
253 }
254
257 if (IsEmpty(*(N))) {
258
259 return 0;
260
261 }
262
265 }
266
283 return;
284 }
17
1.2.3 Entradas
1.2.4 Salidas
18
2 Segundo Parcial
2.1 Listas Simplemente Enlazadas
La lista enlazada es un TDA que nos permite almacenar datos de una forma
organizada, al igual que los vectores pero, a diferencia de estos, esta estructura
es dinámica, por lo que no tenemos que saber ”a priori” los elementos que puede
contener.
19
2.1.2 Código en C
9 unsigned X;
10 unsigned Y;
11 char Color[30];
12 struct Punto *sig;
13
14 }Punto;
15
16
17 /*Variables Globales*/
18 Punto *Head = 0;
19 Punto *Tail = 0;
20 Punto *apP;
21
22
23 /*Zona de prototipos*/
24
20
39 Entradas: Recibe como parametro la lista tipo Punto* y el elemento a
agregar tipo Punto.
40 Salidas: Como la funcion es tipo void no regresa nada pero se agrega el
nodo.*/
41 void AddFirst(Punto *H, Punto Nodo);
42
73
74 int main()
75 {
76 //Creamos la lista
77 //Head = CreaLSE();
21
78
82 //CapturaN(&item2);
83 //CapturaN(&item3);
84 //CapturaN(&item4);
85 //AddFirst(Head, item2);
86 //AddFirst(Head, item3);
87 //AddLast(Head, item4);
88 //ListarLSE(Head);
89 //X = EliminarXATLSE(Head);
90 //ListarLSE(Head);
91 //Y = EliminarXATLSE(Head);
92 //ListarLSE(Head);
93
94
95 //EliminarLSE(Head);
96
97 char M, Res;
98
99
102 M = MMenu();
103 scanf("\n%c", &Res);
104
105 switch(Res){
106
109 printf("\na\n");
110
115 }else{
116
120 break;
121
124 printf("\nb\n");
125 if(Head == 0){
126
22
127 printf("\nTiene que crear la lista primero para
Insertarr\n");
128
129 }else{
130
136 break;
137
140 printf("\nc\n");
141 if(Head == 0){
142
145 }else{
146
152 break;
153
156 printf("\nd\n");
157 //Si no se creo la lista
158 if(Head == 0){
159
162 }
163
168 }else{
169
172 int X;
173 X = EliminarXALSE(Head);
174
23
175 }
176
177 break;
178
181 printf("\ne\n");
182 //Si no se creo la lista
183 if(Head == 0){
184
187 }
188
189
194 }else{
195
198 int X;
199 X = EliminarXATLSE(Head);
200
201 }
202
203 break;
204
210 ListarLSE(Head);
211
212 }
213
214 break;
215
218 printf("\ng\n");
219 if(Head != 0){
220
221 EliminarLSE(Head);
222
223 }
24
224
225 break;
226
231 default:
232 printf("\nOpcion invalida seleccione una opcion existente");
233 break;
234 }
235 }
236
237
238
239 return 0;
240 }
241
242
243
270
25
274 return Head;
275
276 }
277
284 }
285
291 }
292
307
308 }
309
317
26
324 }
325
326 else{
327
332
333 }
334
335 return;
336
337 }
338
341 //Inicializacion
342 Punto *apP = H;
343 Punto *aux = H->sig;
344 Punto *NewNodo = 0;
345
354 }
355
360 return;
361
362 }
363
364
27
374 printf("\nNo se puede eliminar elemento porque la lista esta
vacia\n");
375
376 return 0;
377
378 }else{
379
383 }
384
385 return 1;
386 }
387
397 return 0;
398
399 }
400
406 }
407
412
418 printf("\n\n");
419
28
422 printf("(%u,%u)%s ->",apP->sig->X, apP->sig->Y, apP->sig->Color);
423 apP = apP->sig;
424
425 }
426
427 return;
428 }
429
444 }
445
446 return;
447 }
29
2.1.3 Entradas
Entrada 1:
1. (Opción del Menú) A (Creamos la lista).
2. (Opción del Menú) B (Insertamos por Adelante por lo cual se realiza la
capturación de datos).
(a) (Variable tipo unsigned) 2 (Coordenada de X).
(b) (Variable tipo unsigned) 3 (Coordenada de Y).
(c) (Variable tipo char) A (Color del punto).
3. (Opción del Menú) B (Insertamos por Adelante por lo cual se realiza la
capturación de datos).
(a) (Variable tipo unsigned) 4 (Coordenada de X).
(b) (Variable tipo unsigned) 5 (Coordenada de Y).
(c) (Variable tipo char) R (Color del punto).
4. (Opción del Menú) C (Insertamos por detras por lo cual se realiza la
capturación de datos).
(a) (Variable tipo unsigned) 6 (Coordenada de X).
(b) (Variable tipo unsigned) 7 (Coordenada de Y).
(c) (Variable tipo char) N (Color del punto).
5. (Opción del Menú) F (Listar de adelante hacia atrás).
6. (Opción del Menú) H (Para salir del Menú, siempre se debe de teclear).
30
Entrada 2:
1. (Opción del Menú) A (Creamos la lista).
2. (Opción del Menú) B (Insertamos por Adelante por lo cual se realiza la
capturación de datos).
(a) (Variable tipo unsigned) 6 (Coordenada de X).
(b) (Variable tipo unsigned) 7 (Coordenada de Y).
(c) (Variable tipo char) N (Color del punto).
3. (Opción del Menú) B (Insertamos por Adelante por lo cual se realiza la
capturación de datos).
(a) (Variable tipo unsigned) 9 (Coordenada de X).
(b) (Variable tipo unsigned) 3 (Coordenada de Y).
(c) (Variable tipo char) J (Color del punto).
4. (Opción del Menú) C (Insertamos por detras por lo cual se realiza la
capturación de datos).
(a) (Variable tipo unsigned) 3 (Coordenada de X).
(b) (Variable tipo unsigned) 6 (Coordenada de Y).
(c) (Variable tipo char) Z (Color del punto).
5. (Opción del Menú) E (Eliminar por atras).
6. (Opción del Menú) D (Eliminar por adelante).
7. (Opción del Menú) F (Listar de adelante hacia atrás).
8. (Opción del Menú) H (Para salir del Menú, siempre se debe de teclear).
31
2.1.4 Salidas
Salida de la Entrada 1:
32
33
Salida de la Entrada 2:
34
2.1.5 Link del Programa
Para consulta puede ingresar al siguiente link para verificar el programa: https:
//code.hackerearth.com/0e69e6u
35
2.2 Listas Doblemente Enlazadas
Una lista doblemente enlazada es una lista lineal en la que cada nodo tiene
dos enlaces, uno al nodo siguiente, y otro al anterior. Las listas doblemente
enlazadas no necesitan un nodo especial para acceder a ellas, pueden recorrerse
en ambos sentidos a partir de cualquier nodo, esto es porque a partir de cualquier
nodo, siempre es posible alcanzar cualquier nodo de la lista, hasta que se llega
a uno de los extremos.
36
Una representación más clara serı́a la sigueinte imagen:
Es una estructura de listas dobles donde cada nodo almacena un lista simple.
37
2.2.2 Código en C
9 unsigned NumSEC;
10 char Cadena;
11 char Nombre[10];
12 float KOW;
13 struct AMILDE *next;
14 struct AMILDE *prev;
15 struct AtLSE *H1;
16
17 }AMILDE;
18
22 unsigned NS;
23 char NomAT[10];
24 float PS;
25 struct AtLSE *next;
26
27 }AtLSE;
28
29 /*Variables Globales*/
30 AMILDE *Head = 0;
31 AMILDE *Tail = 0;
32 AtLSE *Tail2 = 0;
33
34
35 /*Zona de Prototipos*/
36
38
43 /*Nombre de la funcion: CreaLDE
44 Descripcion de la funcion: Esta funcion la utilizo para crear la lista
doble vacia.
45 Entradas: Recibe como parametro 2 variables tipo AMILDE** que son Head y
Tail para poder guardar la lista.*.
46 Salidas: Como la funcion es tipo void no regresa nada pero ya tienes la
conexion de Head y Tail para poder utilizar la lista doble.*/
47 void CreaLDE(AMILDE **H, AMILDE **T);
48
39
77 void ListarLDE_ATAD(AMILDE *H, AMILDE *T);
78
40
116 Descripcion de la funcion: Esta funcion la utilizo para modificra un
Aminoacido de la lista doble, se le pide al usuario el Aminoacido a
modificar y que desea modificar. Realiza la busqueda del Aminoacido
y lo modifica.
117 Entradas: No recibe ningun parametro.
118 Salidas: Como la funcion es tipo void no regresa nada, pero se modifica
el Aminoacido.*/
119 void ModificarA();
120
41
149 Entradas: Recibe una variable tipo AtLSE* (La Lista simple).
150 Salidas: Como la funcion es tipo void no tiene salida, pero imprime toda
la lista simple.*/
151 void ListarLSE(AtLSE *H);
152
42
187 void ModAT(AtLSE *H);
188
209
212 M = MMenu();
213 scanf("\n%c\n", &Res);
214
215 switch(Res){
216
223 }else{
224
228 break;
229
230
233 CapturaA(&item);
234 printf("\n\n\n");
43
235 Inser = AddxOrdLDE(Head, Tail, item);
236 printf("\n\n\n");
237
238 break;
239
245 break;
246
249 ListarLDE_ATAD(Head,Tail);
250 printf("\n\n\n");
251
252 break;
253
258 break;
259
262 ModificarA();
263
264 break;
265
270 break;
271
276 break;
277
44
284 if( Crea == 0){
285
288 }else{
289
293 break;
294
295
302 if(NODO.H1 == 0 ){
303
306 }else{
307
314
315 break;
316
317
324 if(NODO.H1 == 0 ){
325
328 }else{
329
45
330 ListarLSE(NODO.H1);
331
332 }
333
334 break;
335
336
347 }else{
348
351 }
352
353 break;
354
355
356
367 }else{
368
371 }
372
373 break;
374
46
376
385 }else{
386
389 }
390
391 break;
392
393
398 default:
399 printf("\nOpcion invalida seleccione una opcion existente");
400 break;
401
402 }
403 }
404
405
406 return 0;
407 }
408
47
424 printf("\n [G] Eliminar Aminoacido (Por Adelante)");
425 printf("\n [H] Eliminar Aminoacido (Por Atras)");
426 printf("\n [I] Insertar LSE de Atomos en Aminoacido");
427 printf("\n [J] Isertar (Atomos) por Orden en LSE");
428 printf("\n [K] Imprimir Lista SE");
429 printf("\n [L] Buscar un tomo de un Aminoacido");
430 printf("\n [M] Eliminar Atomo (Por Adelante)");
431 printf("\n [N] Eliminar Atomo (Por Atras)");
432 printf("\n [Z] Salir del Programa \n");
433
456 }
457
469 return;
470 }
471
48
474
481 NS = NumSECFind(A->NumSEC);
482 if (NS == 0){
483
488 }
489
502 return;
503 }
504
515 return 1;
516 }
517
49
523 apA = apA->next;
524
525 return 0;
526
527 }
528
529 }
530
531 }
532
547 return;
548 }
549
553 printf("\n\n");
554 printf("\n\tAminoacido Encontrado:\t");
555 printf("\n\tNombre: %s", Nodo->Nombre);
556 printf("\n\tNumero Secuencial: %u", Nodo->NumSEC);
557 printf("\n\tCadena: %c", Nodo->Cadena);
558 printf("\n\tCoeficiente de particion: %.2f", Nodo->KOW);
559
560 return;
561 }
562
50
573 //Verificacin de Memoria
574 if( (NewNodo = ((AMILDE*)malloc(sizeof(AMILDE)))) == 0){
575
576 return 0;
577 }
578
594 return 1;
595
596 }
597
610 return 0;
611
621 return 1;
622 }
51
623
636 return 0;
637
638 }
639
651 }
652
52
672 ImprimeAminoacido(apA);
673
678 return;
679 }
680
709 return;
710 }
711
717 printf("\n\n");
718 printf("\nIngrese el Numero Secuencial del Aminoacido que requiere
buscar: ");
53
719 scanf("\n%u\n", &SEC);
720 printf("\nEl Numero tecleado para buscar es: %u\n", SEC);
721
736 return 0;
737 }
738
746 if ( apA->NumSEC == N ){
747
748 printf("\n|-------------------------------------------------------------------------------|\n");
749 printf("\n|\tEl Numero Secuencial si pertenece a un Aminoacido de la
ListaDE. \t|\n");
750 printf("\n|-------------------------------------------------------------------------------|\n");
751 ImprimeSearch(apA);
752 printf("\n\n");
753 printf("\n|-------------------------------------------------------------------------------|\n");
754 return apA;
755
756 }
757
760 }
761
54
767 void ModificarA(){
768
769
770 AMILDE *Q = 0;
771 //unsigned N = 9;
772 int M;
773
776 do{
777
787 switch(M){
788
789 case 1:
790
794 break;
795
796 case 2:
797
801 break;
802
803 case 3:
804
808 break;
809
810 case 4:
811
815 break;
816
55
817
818 case 0:
819
822 break;
823
824 default:
825 printf("\nOpcion invalida, seleccione otra.\n");
826 break;
827 }
828
829
832 return;
833 }
834
850 }
851
859 }
860
865 return 1;
866 }
56
867
883 return;
884 }
885
899 return;
900 }
901
57
917 }
918
932 //Conectamos
933 if(apAt->next == Tail2){
934
938 }else{
939
944 return 1;
945 }
946
953 printf("\n\n");
954
960 }
961
962 return;
963 }
964
58
966 unsigned FindNS(){
967
970 printf("\n\n");
971 printf("\nIngrese el Numero Secuencial del Atomo que requiere
buscar: ");
972 scanf("\n%u\n", &SEC);
973 printf("\nEl Numero tecleado para buscar es: %u\n", SEC);
974
981 printf("\n\n");
982 printf("\n\tAtomo Encontrado:\t");
983 printf("\n\tNombre: %s", Nodo->NomAT);
984 printf("\n\tNumero Secuencial: %u", Nodo->NS);
985 printf("\n\tPorcentaje de Superficie Expuesta: %.2f", Nodo->PS);
986
987 return;
988 }
989
1001 return 0;
1002
1003 }
1004
1014 printf("\n|-------------------------------------------------------------------------------|\n");
59
1015 printf("\n|\tEl Numero Secuencial si pertenece a un Atomo de la
ListaSE. \t\t|\n");
1016 printf("\n|-------------------------------------------------------------------------------|\n");
1017 ImprimeSearchAT(apAT);
1018 printf("\n\n");
1019 printf("\n|-------------------------------------------------------------------------------|\n");
1020
1029 return 0;
1030 }
1031
1044 return 0;
1045
1054 return 1;
1055 }
1056
60
1064 //Si esta vacia
1065 if (aux1 == Tail2 && aux2 == Tail2){
1066
1069 return 0;
1070
1071 }
1072
1084 return 1;
1085 }
1086
1090 AtLSE *Q = 0;
1091 int MM;
1092
1093 Q = QueryNS(H);
1094
1095
1096 do{
1097
1106 switch(MM){
1107
1108 case 1:
1109
61
1113 break;
1114
1115 case 2:
1116
1120 break;
1121
1122 case 3:
1123
1127 break;
1128
1129
1130 case 0:
1131
1132 printf("\nSaliendo...\n");
1133
1134 break;
1135
1136 default:
1137
1140 break;
1141 }
1142
1145
1146 return;
1147 }
62
2.2.3 Entradas
A Crear Lista DE:
Es necesario teclear ’A’ como primera entrada para crear la lista doble-
mente enlazada.
Ejemplo:
A
5
D
VAL
87.95
63
E Buscar un Aminoacido en LDE
Para buscar un Aminoácido necesitamos saber su número secuencial. Por
lo que al ingresar ’E’ con un salto de linea se coloca el número del aminoácido.
Ejemplo:
E
5
F Modificar Aminoacido
Para modificar un aminoácido cree un submenú para seleccionar 1, varias
o todas la opciones. Es necesario ingresar ’F’ seguido del aminoácido que
se va a modificar ’5’ y después la opciones seguido del nuevo cambio.
64
I Insertar LSE de Átomos en Aminoacido
Para crear la lista simple vacı́a para los átomos tiene que ingresar el
número secuelcial del aminoácido en cual quiera crear átomos. Para ello
ingrese ’I’ seguido del número secuencial ’5’.
Ejemplo:
I
5
Ejemplo:
J
5
1
CA
15.65
K Imprimir Lista SE
Para imprimir la lista simple necesitamos ingresar ’K’ seguido del número
secuencial.
Ejemplo:
K
5
65
M Eliminar Átomo (Por Adelante).
Para eliminar por adelante necesitamos el aminoácido, ya que lo que
pasamos es la lista simple del aminoácido.
Ejemplo:
M
5
66
2.2.4 Salidas
Explicación de la salida general:
67
(b) Listar LDE de adelante hacia atrás
Figure 9: Aminoácidos
68
(b) Salir del programa
69
(a) Busqueda de aminoácido
70
(a) Modificar aminoácido
71
(b) Creación de LSE de átomos
72
(b) Busqueda de Aminoácido
(a) Insertar Átomo
73
(b) Insertar átomo
(a) Busqueda de átomo
74
(a) Insertar átomo
75
(a) Imprimir la lista de átomos del Aminoacido
76
(a) Busqueda
(b) Busqueda
77
(a) Por atrás y por adelante
78
2.3 Tablas Hash
Las tablas hash son estructuras de datos que se utilizan para almacenar un
número elevado de datos sobre los que se necesitan operaciones de búsqueda e
inserción muy eficientes. Una tabla hash almacena un conjunto de pares “(clave,
valor)”. La clave es única para cada elemento de la tabla y es el dato que se
utiliza para buscar un determinado valor. Un diccionario es un ejemplo de
estructura que se puede implementar mediante una tabla hash. Para cada par,
la clave es la palabra a buscar, y el valor contiene su significado. El uso de esta
estructura de datos es tan común en el desarrollo de aplicaciones que algunos
lenguajes las incluyen como tipos básicos.
79
80
2.3.2 Código en C
6 /*Estructura Hash*/
7 typedef struct Nodo{
8
9 char *Palabra;
10 struct Nodo *Next;
11
12 }Nodo;
13
14 typedef struct{
15
16 Nodo *Head;
17 Nodo *Tail;
18 int NumArrglo;
19
20 }THash;
21
22 /*Zona de prototipos*/
23
81
40 Entradas: Recibe como parametro la tabla hash tipo Thash, el nuevo nodo
que se agregara a la lista y la key que se utilizara para buscar la
posicion del Array.
41 Salidas: Como la funcion es tipo void no regresa nada pero se agrega el
nodo.*/
42 void AddFirst(THash *A, Nodo NewPalabra, int Mod);
43
56 /*Variables globales*/
57 THash *Array = 0;
58 int TAMAX = 30;
59 int size = 0;
60
61 /* Arbol de Transacciones*/
62 typedef struct Nodo_AT{
63
64 char *URL;
65 char *Candidato;
66 char *Word;
67 int ASCII;
68 struct Nodo_AT *Nleft;
69 struct Nodo_AT *Nrigh;
70
71 }Nodo_AT;
72
73 /*Arbol de Dupla*/
74 typedef struct Nodo_DU{
75
76 char *Candidato;
77 char *Word;
78 int DUPLA;
79 int ASCII;
80 struct Nodo_DU *Nleft;
82
81 struct Nodo_DU *Nrigh;
82
83 }Nodo_DU;
84
85
83
120
84
154 Salidas: Como la funcion es tipo void no regresa nada pero imprime en
Postorden.*/
155 void POSTORDU_R(Nodo_DU *R);
156
163 }Candidato;
164
85
196 Descripcion de la funcion: Esta funcion la utilizo para agregar al
principio de la lista un Nodo tipo Candidato.
197 Entradas: Recibe como parametro la lista 2 tipo Candidato* Head y Tail,
el nuevo nodo que se agregara a la lista tipo Candidato.
198 Salidas: Como la funcion es tipo void no regresa nada pero se agrega el
nodo.*/
199 void AddFirst(Candidato *H, Candidato *T, Candidato Nodo);
200
213
86
236 int RES;
237
238
249 Nodo P;
250 int CN;
251 char Pa[30] = "DIEGO";
252 int Pos;
253 printf("\n%s", Pa);
254
267
268 /*
269 printf("\nEscriba la palabra:\n");
270 fgets(texto, 30, stdin);
271
87
284
285 getchar();
286 return 0;
287 }
288
298 }
299 else{
300
307 return 1;
308 }
309
312 int i, j, k;
313 int l = 0;
314 int m = 0;
315 int NUM;
316
330
88
334 Array[i].Head = (Nodo*)malloc(sizeof(Nodo));
335 Array[i].Tail = (Nodo*)malloc(sizeof(Nodo));
336 Array[i].NumArrglo = NUM;
337 NUM++;
338
364 }
365 }
366
367 printf("\n\n");
368
375 }
376
89
379 printf("\nSe conecto correctamente Head y Tail.\n");
380 l++;
381
382 }
383
389 }
390
391 return 1;
392 }
393
396 int i = 0;
397 int Suma = 0;
398 int Mod;
399
406 }
407
412
418 //Inicializacion
419 THash *apH = A;
420 Nodo *apHMOD = apH[Mod].Head;
421 Nodo *Tail = apH[Mod].Tail;
422 Nodo *NewNodo = 0;
423
90
429 printf("\nNo se creo la memoria correctamente.\n");
430 }
431 else{
432
463
464 return;
465 }
466
469 int i;
470
91
477 if(temp->Next == aux){
478
487 }
488
489 printf("\n");
490 }
491
492
493 }
494
505
513
518
522
523 }
524
92
527
528 fclose(Archivo);
529
530 }
531 else{
532
537 return 1;
538 }
539
540
557 }
558
573 //Funcion que calcula la suma de todos los campos de cada Nodo
574 int Suma_ASCII(char *url, char *c, char *w){
575
576 int i = 0;
93
577 int j = 0;
578 int k = 0;
579
591 }
592
593
602 }
603
604
613 }
614
94
627
658 return;
659 }
660
673 if (R->Nrigh != R)
674 {
675 //Llamada recursiva para der
676 R_PRE(R->Nrigh);
95
677 }
678
679 return;
680 }
681
688 R_INOR(R->Nleft);
689
690 }
691
698 R_INOR(R->Nrigh);
699 }
700
701 return;
702 }
703
710 R_POSTOR(R->Nleft);
711 }
712
716 R_POSTOR(R->Nrigh);
717 }
718
722 return;
96
723 }
724
725
726
742 }
743
757 //Funcion que calcula la suma de todos los campos de cada Nodo
758 int Suma_ASCIIDU(char *c, char *w){
759
760 int j = 0;
761 int k = 0;
762
767
97
773 Suma2 = Suma2 + c[j];
774 j++;
775
776 }
777
778
787 }
788
98
823 }
824
832 return;
833 }
834
847 if (R->Nrigh != R)
848 {
849 //Llamada recursiva para der
850 PREDU_R(R->Nrigh);
851 }
852
853 return;
854 }
855
862 INORDU_R(R->Nleft);
863
864 }
865
99
871
872 INORDU_R(R->Nrigh);
873 }
874
875 return;
876 }
877
884 POSTORDU_R(R->Nleft);
885 }
886
890 POSTORDU_R(R->Nrigh);
891 }
892
896 return;
897 }
898
914 }
915
100
919 //Por si no hubo error en H
920 free(Head_AMLO);
921 return Tail_AMLO;
922
923 }
924
936 }
937
950 }
951
959 }
960
101
969
972 }
973
986 }
987
995 }
996
1008 }
1009
102
1019 //printf("No hay espacio de memeria para crear la Lista (H)");
1020 return Head_Zavala;
1021
1022 }
1023
1031 }
1032
1044 }
1045
1055 }
1056
1059 return 1;
1060 }
1061
1065 //Inicializacion
1066 Candidato *apC = H;
1067 Candidato *NewNodo = 0;
1068
103
1069 //Asignacion de memoria
1070 NewNodo = (Candidato*)malloc(sizeof(Candidato));
1071
1098 }
1099
1102 //printf("\nYEAP.");
1103 }
1104 else{
1105
1106 //printf("\nNOOO");
1107 }
1108
1109 //printf("\nOK");
1110
1111 return;
1112 }
1113
104
1119
1127 }
1128
1134 }
1135
1136 apC->Next = T;
1137 free(aux1);
1138
1139 return 1;
1140 }
1141
1148 printf("\n\n");
1149
1150
1157 return;
1158 }
1159
105
1168
1173
1204 return 1;
1205 }
1206
1216
106
1218 Candidato item, item1, item2, item3, item4;
1219 int X, X1, X2, X3, X4;
1220
1250 return 1;
1251 }
1252
1262
107
1268
1296 return 1;
1297 }
1298
108
1318
1335 return 1;
1336 }
109
3 Tercer Parcial
3.1 Grafos
El origen de la palabra grafo es griego y su significado etimológico es ”trazar”.
aparece con gran frecuencia como respuesta a problemas de la vida cotidiana,
algunos ejemplos podrı́an ser los siguientes:un gráfico de una serie de tareas a
realizar indicando su secuenciación (un organigrama), grafos matemáticos que
representan las relaciones binarias, una red de carreteras, la red de enlaces
ferroviarios o aéreos o la red eléctrica de una ciudad, (ver la figura 1). En
cada caso es conveniente representar gráficamente el problema dibujando un
grafo como un conjunto de puntos (nodos o vértices) con lı́neas conectándolos
(arcos).
110
3.1.1 Descripción de Programa
Codifique los algoritmo de búsqueda BFS y DFS para un grafo dado mediante
su lista de adyacencia Realice las estructuras de datos y funciones necesarias.
Envı́en el enlace del programa en Hacker eart
3.1.2 Código en C
7 //Estructuras de datos
8 typedef struct queue //Estructura de cola
9 {
10 int QueueVer[30]; //Defino cantidad de vertices del tamano de la
cola
11 int adelante; //Nodo siguiente
12 int atras; //Nodo anterior
13 }queue;
14
28
29 //Prototipos de funciones
30 struct grafo* CreaGrafo(int vertices);
31 struct queue* CreaCola();
32 void Encolar(struct queue* q, int);
33 int isempty(struct queue* q);
34 int DesEncolar(struct queue* q);
35 struct nodo*CreaNodo(int);
36 void addRelacion(struct grafo* graph, int desde, int hacia);
111
37 void BFS(struct grafo* graph, int iniciavertices);
38 void imprimircola(struct queue *q);
39 void imprimirgrafo(struct grafo* graph);
40 void DFS(struct grafo*, int);
41
42
43 //Funcion principal
44 int main()
45 {
46 int i;
47 int vert;
48 int start;
49 unsigned menu;
50
54
73 if(menu == 1)
74 {
75
76 BFS(graph, 0);
77 imprimirgrafo(graph);
78 }
79 else if(menu == 2)
80 {
81
85 DFS(graph, start);
112
86 imprimirgrafo(graph);
87 }
88 else
89 {
90 printf("\n Opcion incorrecta");
91 }
92
93
94
95 return 0;
96 }
97
129
113
132 //Entradas: Nada.
133 //Salidas: La cola (q).
134 struct queue* CreaCola()
135 {
136 struct queue* q=malloc(sizeof(struct queue));
137 q->adelante=-1;
138 q->atras=-1;
139 return q;
140 }
141
179
114
182 //Entradas: La cola.
183 //Salidas: Regresa el vertice.
184 int DesEncolar(struct queue* q)
185 {
186 int vertice;
187 if(isempty(q))
188 {
189 printf("La cola esta vacia");
190 vertice=-1;
191 }
192 else
193 {
194 vertice=q->QueueVer[q->adelante];
195 q->adelante++;
196 if(q->adelante>q->atras)
197 {
198 q->adelante=q->atras=-1;
199 }
200 }
201 return vertice;
202 }
203
204
115
231 void imprimirgrafo(struct grafo* graph)
232 {
233 int v;
234 for (v = 0; v < graph->numver; v++)
235 {
236 struct nodo* temp = graph->listadj[v];
237 printf("\n Lista de adyacencia del vertice %d\n ", v);
238 while (temp)
239 {
240 printf("%d -> ", temp->vertice);
241 temp = temp->next;
242 }
243 printf("\n");
244 }
245 }
246
247
276
116
281 void DFS(struct grafo* graph, int ini)
282 {
283 struct nodo* listadj=graph->listadj[ini];
284 struct nodo* temp=listadj;
285 graph->color[ini]=1;
286 while(temp!=NULL)
287 {
288 int vectorenlazado=temp->vertice;
289 if(graph->color[vectorenlazado]==0)
290 {
291 DFS(graph, vectorenlazado); //Manado a llamar de manera
recursiva a DFS
292 }
293 temp=temp->next;
294 }
295 printf("\nLa busqueda DFS ha terminado\n");
296 }
297
298
299
117
3.1.3 Entradas
3.1.4 Salidas
118
3.2 Búsquedas: DFS y BFS
El recorrido que se hace con este tipo de algoritmos es a cı́clico por lo que se
dice que el recorrido es de árbol, sin embargo la entrada sigue siendo un grafo.
119
3.2.1 Descripción de Programa
Codifique los algoritmo de búsqueda BFS y DFS para un grafo dado mediante
su lista de adyacencia.
3.2.2 Código en C
5 #define TRUE 1
6 #define FALSE 0
7 #define SIZE 10
8
9 #define White 1
10 #define Gray 2
11 #define Black 3
12
13
22 char *Vertice;
23 unsigned Num;
24 struct Nodo_Ver *Head;
25 struct Nodo_Ver *Tail;
26
27 }MLista;
28
29
33 char *Vertice;
34 unsigned Numseq;
35 struct Nodo_Ver *Next;
36
37 }Nodo_Ver;
38
120
39 //Estructura del Nodo de la cola
40 typedef struct Nodo_Q{
41
42 Nodo_Ver *Data;
43 struct Nodo_Q *prev;
44
45 }Nodo_Q;
46
50 unsigned Size;
51 Nodo_Q *Head;
52 Nodo_Q *Tail;
53 unsigned Limit;
54
55 }Queuei;
56
57 /*Variables Globales*/
58 unsigned NumV;
59 char *Verti = 0;
60 MLista *Array = 0;
61 Queuei *Queue = 0;
62
63
64
65 /*Zona de Prototipos*/
66
121
86 Descripcion de la funcion: Esta funcion se usa para inicializar la
matriz de adyacnecia vacia del tam de vertices..
87 Entradas: Recibe como parametro una variable tipo unsigned que indica el
numero de vertices.
88 Salidas: Como la funcion es tipo int regresa 1 si se creo
correctamente.*/
89 int Init_ArrayLinked(unsigned Size);
90
122
123 /*Nombre de la funcion: Enqueue
124 Descripcion de la funcion: Esta funcion se usa para inserta un vertice a
la cola.
125 Entradas: Recibe como parametro a la colo tipo Queuei* y el nuevo
elemento.
126 Salidas: Como la funcion es tipo int, regresa 1 si se inserto el
elemento.*/
127 int Enqueue(Queuei *Q, Nodo_Q *item);
128
141
142 //BFS
143
156
123
162 Salidas: Como la funcion es tipo void no regresa nada pero imprime.*/
163 void ImprimeArrayD(int *D);
164 void ImprimeArrayC(int *C);
165 void ImprimeArrayF(int *F);
166
167
194
195 S = SelecV(Array);
196
202
203 //printf("\n\n");
204 //ImprimeArrayC(Color);
205 //ImprimeArrayF(Fathersuki);
206 //ImprimeArrayD(Distancia);
207 }
208
209 }
210
124
212
213
214 }
215
216
217 printf("\nFINAL\n");
218
219 ImprimeArrayC(Color);
220 ImprimeArrayF(Fathersuki);
221 ImprimeArrayD(Distancia);
222
223 //DisplayQ();
224
225 return 0;
226 }
227
228
238 return;
239 }
240
243 //Inicializacion
244 char Vertices[30];
245 int j = 0;
246 char *P = 0;
247 char *Ver = 0;
248 unsigned Po = 0;
249 unsigned Pos = 0;
250 MLista item;
251
255 P = Vertices;
256 //printf("\n%s", P);
257
125
262 Ver = P[j];
263 //printf("\n%c", P[j]);
264 CapturaN(&item, Ver);
265 //printf("\nPos: %u", Pos);
266 AddT(Array, Ver, Pos);
267 Pos++;
268 }
269 }
270
271 return;
272 }
273
289 P = Vertices;
290 //printf("\n%s", P);
291
292
304 //Inicializacion
305 Nodo_Ver *apH = Array[i].Head;
306 Nodo_Ver *aux = Array[i].Head->Next;
307 Nodo_Ver *N = 0;
308
126
312 if( (N = (Nodo_Ver*)malloc(sizeof(Nodo_Ver))) == 0){
313
321
329 //printf("\nAgregando..");
330 N->Next = aux;
331 apH->Next = N;
332 N->Vertice = Ver;
333 N->Numseq = Posicion;
334 }
335 }
336
337 }
338 return;
339 }
340
346 return;
347 }
348
351 //Inicializacion
352 MLista *apH = A;
353
357 return;
358 }
359
127
362
363 int i, j, k, l;
364 int m = 0;
365
379
380
387
128
407 //printf("\nNo se creo correctamente la lista vacia del
arreglo[%d].", j);
408 return -1;
409 }
410 else{
411
414 }
415 }
416
417
418 //printf("\n\n");
419
426 }
427
441 printf("\n\n");
442
129
455
456 return 1;
457
458 }
459
463 unsigned i;
464
478 int i;
479 MLista *apL = Array;
480
481 printf("\n\n");
482
485
486
491 }
492 else{
493
494 //Inicializacion
495 Nodo_Ver *apH = apL[i].Head;
496 Nodo_Ver *aux = apL[i].Tail;
497
130
502 printf("--> | %c / %u |", apH->Next->Vertice,
apH->Next->Numseq);
503 apH = apH->Next;
504 }
505
506 }
507 printf("\n");
508
509 }
510
511 return;
512 }
513
514
515
535
547 //Inicializacion
548 char *NV = 0;
549 int i;
550
131
551 printf("\nCon que vertice quiere empezar");
552 scanf("%s", &NV);
553
556
567 }
568 else{
569
574 }
575
579 //Inicializacion
580 Nodo_Q *item = 0;
581
597 }
598
132
600 item->Data->Vertice = NV;
601 item->Data->Numseq = Po;
602
609 //Inicializacion
610 char *NV = 0;
611 Nodo_Q *Newitem;
612 int i;
613
614
632 }
633
133
650
134
698 //Agregamos el elemento uno antes del Prev y igualamos Tail al
agregado
699 Q->Tail->prev = item;
700 Q->Tail = item;
701 }
702
703 Q->Size++;
704
711 //Inicializacion
712 Nodo_Q *item;
713
717 return 0;
718 }
719 else{
720
734 }
735
135
747 printf("\nNo hay elementos en la cola.");
748 return TRUE;
749 }
750 else{
751
756
785 return;
786 }
787
791 //Inicializacion
792 int i;
793 Nodo_Ver *NV = 0;
794
136
795 for(i = 0; i < NumV; i++){
796
799 //Inicializacion
800 Nodo_Ver *apH = Array[i].Head;
801 Nodo_Ver *aux = Array[i].Tail;
802
811 }
812
813 }
814
815 }
816
820
821 //Inicializacion
822 unsigned i;
823 int Q, Q1;
824 Nodo_Q *item = 0;
825 Nodo_Q *Del = 0;
826
137
845 //Creamos un elemento tipo Nodo_Q* con los datos de Vertice de inicio
846 item = SelecVML(Array, PO);
847
859 }
860 else{
861
865
868 //Incializacion
869 int i;
870 char *V = 0;
871 unsigned U;
872 int u;
873
888
893 //Inicializacion
894 Nodo_Ver *apH = Array[i].Head;
138
895 Nodo_Ver *aux = Array[i].Tail;
896 unsigned Poss;
897
900 //Inicializacion
901 Nodo_Ver *NV = 0;
902
903
904
911 /*
912 if( Color[Poss] == White){
913
914 //Inicializacion
915 int Qq;
916 Nodo_Q *Nitem = 0;
917
139
942 printf("\nCambio de Gray a Black del Vertice
%u\n", Poss);
943 ImprimeArrayC(Color);
944 ImprimeArrayF(Fathersuki);
945 ImprimeArrayD(Distancia);
946
950 */
951
959 }
960
964 }
965
966 //}
967
971
976 }
977 else{
978
985
986
987 return;
988 }
140
989
990 //
991
995 //Inicializacion
996 int i;
997
1000
1003
1004 }
1005
1006 return;
1007 }
1008
1012 //Inicializacion
1013 int i;
1014
1019 }
1020
1021 printf("\n\n");
1022 return;
1023 }
1024
1028 //Inicializacion
1029 int i;
1030
1036 printf("\n\n");
1037 return;
1038 }
141
142
3.2.3 Entradas
3.2.4 Salidas
143
3.3 MST: Minimum Spanning Tree
Árbol de expansión: Un árbol de expansión es aquel árbol que enlaza todos los
nodos de la red, de igual manera no permite la existencia de ciclos.
144
El árbol de expansión mı́nimo tiene aplicación directa en el diseño de redes.
Se usa en algoritmos que se aproximan al problema del vendedor ambulante, el
problema de corte mı́nimo en múltiples terminales y el emparejamiento perfecto
ponderado de costo mı́nimo. Otras aplicaciones prácticas son:
1. Análisis de conglomerados.
2. Reconocimiento de escritura a mano.
3. Segmentación de imagen.
Paso 1:
Paso 2:
Ahora se debe seleccionar el nodo j del conjunto ČK-1 (es decir del conjunto
del paso 1) el cual presente el arco con la menor longitud y que se encuentre
enlazado con uno de los nodos de enlace permanente del conjunto Ck-1 en el
cual ahora solo se encuentra el nodo 1 (es decir que se debe de encontrar un
nodo que tenga el arco de menor longitud enlazado al nodo 1).
145
3.4 Algoritmo de Kruskal
Descripción del Algoritmo:
Este algoritmo permite que, dado un grafo no dirigido, pueda encontrar un árbol
de expansión mı́nima, en otras palabras, encontrar subconjuntos de arista que
lleguen a formar un árbol que incluya todos los vértices del grafo original, dado
que su peso total en las aristas del árbol sea mı́nimo.
146
147
3.4.1 Código
148
3.5 Algoritmo de Prim
Descripción del Algoritmo:
El algoritmo de Prim es un algoritmo perteneciente a la teorı́a de los grafos para
encontrar un árbol recubridor mı́nimo en un grafo conexo, no dirigido y cuyas
aristas están etiquetadas.
149
Listing 9: Programa en C de Prim
1 //**** Comienza Archivo grafo.h *****//
2 #include <vector>
3
18
24 Grafo::Grafo(int nodos)
25 {
26 this->cn = nodos;
27 this->ady = vector< vector<int> > (cn);
28
44 int padre = 0;
45 int hijo = 0;
46 while(markedLines.size() + 1 < cn){
47 padre = hijo;
48 // Marco la fila y elimino la columna del nodo padre.
150
49 markedLines.push_back(padre);
50 for(int i = 0; i < cn; i++)
51 adyacencia[i][padre] = INF;
52
64 arbol[padre][hijo] = min;
65 arbol[hijo][padre] = min;
66 }
67 return arbol;
68 }
69 //**** Finaliza Archivo grafo.cpp *****//
151