Está en la página 1de 152

Universidad del Caribe

Ingenierı́a en Datos e Inteligencia Organizacional

Diseño de patrones para datos


Clave: ID0101

Proyecto Final
Todos los Parciales
Programas

Dr. David Israel Flores Granados

Gutiérrez May Diana Aimeé


160300115@ucaribe.edu.mx
May 14, 2018
Para los que siempre confiaron en lo que podı́a lograr.

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

3 Tercer Parcial 110


3.1 Grafos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
3.1.1 Descripción de Programa . . . . . . . . . . . . . . . . . . 111
3.1.2 Código en C . . . . . . . . . . . . . . . . . . . . . . . . . 111
3.1.3 Entradas . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
3.1.4 Salidas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
3.1.5 Link del Programa . . . . . . . . . . . . . . . . . . . . . . 118
3.2 Búsquedas: DFS y BFS . . . . . . . . . . . . . . . . . . . . . . . 119
3.2.1 Descripción de Programa . . . . . . . . . . . . . . . . . . 120
3.2.2 Código en C . . . . . . . . . . . . . . . . . . . . . . . . . 120
3.2.3 Entradas . . . . . . . . . . . . . . . . . . . . . . . . . . . 143
3.2.4 Salidas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143
3.2.5 Link del Programa . . . . . . . . . . . . . . . . . . . . . . 143

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.

Figure 1: Representación de un Apuntador

1.1.1 Descripción de Programa


Realizar un programa que calcule el factor correlacional de Spearman máximo
para cada evento que se registre en un sistema de detección de movimientos.
Cada evento es un experimento que calcula la relación del movimiento real
del usuario con todos los posibles movimientos en los que se puede clasificar
de acuerdo a la detección mediante un dispositivo (SALTO(J), TROTE(R),
CAÍDA(F), SACUDIDA(S)) . Los eventos se para cada posible movimiento se
registran con la siguiente información :

ID de usuario - Tipo Cadena


Dia - Tipo char sin signo.
Mes - Tipo char sin signo.
Movimiento - Tipo char (J, R, F, S).
Coeficiente de Spearman (rho) para el movimiento. - flotante.

El número de experimentos a capturar es variable por cada versión del sis-


tema de detección pero el conjunto de movimientos a detectar es fijo, es decir,
siempre son cuatro.
Los usuarios tienen que ingresar un nombre de usuario de 3 letras y 4 dı́gitos.
1. La primera letra indica el sexo del usuario: Masculino o Femenino.
2. La segunda letra indica la edad del usuario: Joven, mediana edad y tercera
edad.
3. La tercera letra indica la complexión del usuario: Pequeña, mediana y
grande.
4. Los primeros dos dı́gitos indican: el número de experimento.
5. Los últimos dos dı́gitos indican: el número de usuario.

4
1.1.2 Código en C

Listing 1: Programa en C enfocado a un examen de experimentos que se alojan


en una matriz.
1 #include <stdio.h>
2 #include <string.h>
3 #include <stdlib.h>
4

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

17 /*Nombre de la funcion: CreaMatriz


18 Descripcion de la funcion: Crea una matriz dinamica de experimentos.
19 Entradas: Dos tipos de datos unsigned que indican el numero de columnas
y filas.
20 Salidas: Regresa la Matriz creada pero vacia*/
21 Experimento **CreaMatriz(unsigned TAMX, unsigned TAMY);
22

23 /*Nombre de la funcion: CapturaMatriz


24 Descripcion de la funcion: Captura los valores de entrada del usuario y
los guarda en la Matriz.
25 Entradas: La Matriz Creada (Vacia).
26 Salidas: Como la funcion es tipo void no regresa nada pero imprime la
Matriz*/
27 void CapturaMatriz(Experimento **ap1);
28

29 /*Nombre de la funcion: main


30 Descripcion de la funcion: Lleva acabo la creacion de las variables para
las funciones. Y prcesa la ejecucion de las funciones con las
variables creadas.
31 Entradas: No contiene entradas.
32 Salidas: Regresa 0 si el programa se realizo correctamente*/
33 int main(){
34

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

44 for(int i = 0; i < 4; i++){


45

46 AP1[i] = (Experimento*)malloc(4*sizeof(Experimento));
47 }
48

49 CapturaMatriz(AP1);
50

51

52 return 0;
53 }
54

55 Experimento **CreaMatriz(unsigned TAMX, unsigned TAMY){


56

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

67 if( (Ex = (Experimento**)malloc(TAMX*sizeof(Experimento))) == 0){


68

69 printf("\nNo se pudo crear la Matriz.");


70 return 0;
71 }
72 else{
73

74 printf("\nLa Matriz se ha creado correctamente.\n");


75 }
76

77 return Ex;
78

79 }
80

81 void CapturaMatriz(Experimento **ap1){


82

83 int i, j;
84

85 for(i = 0; i < 4; i++){


86

87 for(j = 0; j < 4; j++){


88

89 printf("\nDigite su Usuario[%d][%d]", i, j);


90

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

100 float Comp[4][4];


101

102 for(i = 0; i < 4; i++){


103

104 for(j = 0; j <4 ; j++){


105

106 Comp[i][j] = ap1[i][j].Rho;


107 }
108

109 }
110

111 for(int k = 0; k < 4; k++){


112

113 for(int i = 0; i < 4; i++){


114

115 for(int j = 0; j < 4; j++){


116

117 if(Comp[k][i] < Comp[k][j]){


118

119 int menor = Comp[k][i];


120 Comp[k][i] = Comp[k][j];
121 Comp[k][j] = menor;
122 }
123 }
124 }
125 }
126

127

128 for(int l = 0; l < 4; l++){


129

130 for(int m = 0; m < 4; m++){


131

132

133 printf("%.7s\t", ap1[l][m].ID_user);


134 printf("%u\t", ap1[l][m].dia);
135 printf("%u\t", ap1[l][m].mes);
136 printf("%c\t", ap1[l][m].movimiento);
137 printf("%.2f\t", ap1[l][m].Rho);
138

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

(a) Capturación de Usuarios


(b) Capturación de usuarios

Figure 2: Proceso de Capturación

9
Matriz de la Base de Datos de los Experimentos:

(a) Base de Datos

(b) Base de Datos

Figure 3: Almacenamiento de Experimentos

1.1.5 Link del Programa


Para consulta puede ingresar al siguiente link para verificar el programa: https:
//code.hackerearth.com/e164c9R

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.

En cada momento sólo se tiene acceso a la parte superior de la pila, es de-


cir, al último objeto apilado (denominado TOS, Top of Stack en inglés). La
operación retirar permite la obtención de este elemento, que es retirado de la
pila permitiendo el acceso al anterior (apilado con anterioridad), que pasa a ser
el último, el nuevo TOS.

Figure 4: Representación de un Apuntador

1.2.1 Descripción de Programa


Realizar un programa en lenguaje C que indique el contenido de las pilas de li-
bros que hay en cada una de las tres mesas contenedoras (A, B y C). El número
máximo de libros que se permite apilar en cada una lo define el usuario.

La función de inserción de un libro sobre la pila de una mesa en especı́fico


se realiza cuando: se indica el nombre de la mesa, el caracter ’ N’ que indica
que se obtuvo una carta Negra de una baraja de naipes y el dato del libro a
insertar en la pila. Por ejemplo: Mesa: A, Carta Negra, ISBN: . Si el libro no
se puede insertar NO desplegará mensaje de error.

La función de extracción de un libro sobre la pila de una mesa en especı́fico


se realiza cuando: se indica el nombre de la mesa y el color de una carta ex-
traı́da de una baraja de naipes es roja. Por ejemplo: Mesa A, Carta Roja
extraerı́a el Libro de Estructuras de Datos. Si no hay libro por extraer NO se
desplegará mensaje de error.

Si el nombre de la mesa es ’*’ entonces se mostrará el contenido de cada una de


las mesas mediante la función de extracción.

11
1.2.2 Código en C

Listing 2: Programa en C para encontrar el ordén de las cartas de la pila.


1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <memory.h>
4 #include <string.h>
5

7 //Estructura de cada pila


8

9 typedef struct Table {


10

11 int size;
12 int top;
13 char **stacki;
14

15 } Table;
16

17

18

19 /*Zona de prototipos*/
20

21 /*Nombre de la funcion: IniStacki


22 Descripcion de la funcion: Crea una Pila del tam indicado vacia con
todos sus componentes.
23 Entradas: Dos tipos de datos, una variable tipo Table para la
inicializacion de la pila y copiar contenidos y la segunda variable
tipo int que es para el tam de la pila.
24 Salidas: Como es tipo void no regresa nada pero, la pila Inicializada se
guarda en la variable creada en la funcion Main*/
25 void IniStacki(Table *N, int S);
26

27 /*Nombre de la funcion: IsEmpty


28 Descripcion de la funcion: Verifica si la pila se encuentra vacia.
29 Entradas: Una variable tipo Pila (Una de las pilas creadas).
30 Salidas: Regresa 1 si esta vacia*/
31 int IsEmpty(Table N);
32

33 /*Nombre de la funcion: IsFull


34 Descripcion de la funcion: Verifica si la pila se encuentra llena.
35 Entradas: Una variable tipo Pila (Una de las pilas creadas).
36 Salidas: Regresa 1 si esta llena*/
37 int IsFull(Table N);
38

39 /*Nombre de la funcion: Pushi


40 Descripcion de la funcion: Inserta un elemento mas a la Pila.
41 Entradas: Una variable tipo Pila (Una de las pilas creadas) y una
varible tipo char que sera el nuevo elemento.

12
42 Salidas: Regresa 1 si se pudo argregar el nuevo elemento*/
43 int Pushi(Table *N, char L[5]);
44

45 /*Nombre de la funcion: Popi


46 Descripcion de la funcion: Elimina el ultimo elemnto que entro a la Pila
.
47 Entradas: Una variable tipo Pila (Una de las pilas creadas).
48 Salidas: Regresa 1 si el ultimo elemento se pudo eliminar.*/
49 int *Popi(Table *N);
50

51 /*Nombre de la funcion: ImprimeWeas


52 Descripcion de la funcion: Imprime el contendio de la Pila.
53 Entradas: Una variable tipo Pila (Una de las pilas creadas) y una
variable tipo char con la letra de la Pila.
54 Salidas: La funcion es tipo void, no regresa nada pero imprime.*/
55 void ImprimeWeas(Table N, char letra);
56

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

67 scanf("%u %u %u", &sA, &sB, &sC);


68 //printf("%u\t %u\t %u\n", sA, sB, sC);
69

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

111 case ’B’:


112

113 scanf("%c\t", &Carta);


114 //printf("Carta: %c\n", Carta);
115

116

117 switch (Carta) {


118

119 case ’N’:


120

121 scanf("%s\n", &Libro);


122 //printf("Libro: %s\n", Libro);
123 Pushi(&B, Libro);
124

125 break;
126

127 case ’R’:


128

129 Popi(&B);
130

131 break;
132 default:
133 break;
134 }
135

136

137 break;
138

139

14
140

141 case ’C’:


142

143 scanf("%c\t", &Carta);


144 //printf("Carta: %c\n", Carta);
145

146

147 switch (Carta) {


148

149 case ’N’:


150

151 scanf("%s\n", &Libro);


152 //printf("Libro: %s\n", Libro);
153 Pushi(&C, Libro);
154

155

156 break;
157

158 case ’R’:


159

160 Popi(&C);
161

162

163 break;
164 default:
165 break;
166 }
167

168

169 break;
170

171

172 default:
173 break;
174 }
175

176 //printf("\n%c\n", Seleccion);


177

178 if (Seleccion == ’*’){


179

180 D++;
181 }
182

183

184 }
185

186 ImprimeWeas(A, ’A’);


187 printf("\n");
188 ImprimeWeas(B, ’B’);
189 printf("\n");

15
190 ImprimeWeas(C, ’C’);
191

192 return 0;
193 }
194

195

196 //Creamos la Matriz de pilas


197 void IniStacki(Table *N, int S) {
198

199 int i;
200

201 N->size = S;
202 N->top = -1;
203

204 //Creamos el espacio de memoria de la matriz


205 N->stacki = malloc(sizeof(char**)*N->size);
206

207 for (i = 0; i < N->size; i++) {


208

209 //Creamos el espacio de 5 en cada uno de los espacios de la pila


210 N->stacki[i] = malloc(sizeof(char*) * 5);
211 }
212

213 return;
214

215 }
216

217 int IsEmpty(Table N) {


218

219 if (N.top < 0) {


220

221 return 1;
222

223 }
224

225 return -1;


226

227 }
228

229 int IsFull(Table N) {


230

231 if (N.top >= (N.size) - 1) {


232

233 return 1;
234

235 }
236

237 return -1;


238

239 }

16
240

241 int Pushi(Table *N, char *L) {


242

243 if (N->top >= N->size-1) {


244

245 return -1;


246

247 }
248

249 strcpy(N->stacki[++N->top], L);


250

251 return 1;
252

253 }
254

255 int *Popi(Table *N) {


256

257 if (IsEmpty(*(N))) {
258

259 return 0;
260

261 }
262

263 return &(N->stacki[N->top--]);


264

265 }
266

267 void ImprimeWeas(Table N, char letra) {


268

269 //MESA [A..C]:\tISBN1\t...\tISBNn


270 int i;
271

272 printf("MESA %c: ", letra);


273

274 for ( i = 0; i < N.top; i++)


275 {
276 printf("%s", N.stacki[i]);
277

278 if(i < N.top -1){


279 printf("\t");
280 }
281 }
282

283 return;
284 }

17
1.2.3 Entradas

1.2.4 Salidas

1.2.5 Link del Programa


Para consulta puede ingresar al siguiente link para verificar el programa: https:
//code.hackerearth.com/8a3192x

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.

En una lista enlazada, cada elemento apunta al siguiente excepto el último


que no tiene sucesor y el valor del enlace es null. Por ello los elementos son
registros que contienen el dato a almacenar y un enlace al siguiente elemento.
Los elementos de una lista, suelen recibir también el nombre de nodos de la
lista.

Figure 5: Esquema de un nodo y una lista enlazada.

2.1.1 Descripción de Programa


Realice un programa en el lenguaje C, que representa el TDA Listas simple-
mente enlazadas. En el cual generé una estructura con ”(2,4)A”, que representa
las coordenadas de un punto y la letra el colo del punto, en este caso ’A’ que
representa azul. Los puntos constan de un valor entero positivo para la coorde-
nada x, un valor entero positivo para la coordenada y, un carácter para indicar
el color.

19
2.1.2 Código en C

Listing 3: Programa en C que representa el TDA Listas simplemente enlazadas.


1 #include <stdio.h>
2 #include <memory.h>
3 #include <string.h>
4 #include <stdlib.h>
5

6 //Declaracion de la estructura Punto


7 typedef struct Punto{
8

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

25 /*Nombre de la funcion: CreaLSE


26 Descripcion de la funcion: Hace la conexion entre Head y Tail (Variables
globales) y les da espacio de memoria tipo Punto. Para asi usar la
lista vacia.
27 Entradas: No recibe entradas.
28 Salidas: Como la funcion es tipo Punto, regresa a Head para utilizarla
como lista.*/
29 Punto *CreaLSE();
30

31 /*Nombre de la funcion: CapturaN


32 Descripcion de la funcion: Recibe las entradas del usuario para
almacenarlas en un Nodo y asi poder agregarlo a la lista.
33 Entradas: Recibe una variable tipo Punto, para copiarlo los valores en
el Nodo.
34 Salidas: Como la funcion es tipo void no tiene salida, pero la variable
que se metio por parametro para Capturar el Nodo se uso, esa es la
que utilizamos.*/
35 void CapturaN(Punto *P);
36

37 /*Nombre de la funcion: AddFirst


38 Descripcion de la funcion: Esta funcion la utilizo para agregar al
principio de la lista un Nodo tipo Punto.

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

43 /*Nombre de la funcion: AddLast


44 Descripcion de la funcion: Esta funcion la utilizo para agregar al final
de la lista un Nodo tipo Punto.
45 Entradas: Recibe como parametro la lista tipo Punto* y el elemento a
agregar tipo Punto.
46 Salidas: Como la funcion es tipo void no regresa nada pero se agrega el
nodo.*/
47 void AddLast(Punto *H, Punto Nodo);
48

49 /*Nombre de la funcion: EliminarXALSE


50 Descripcion de la funcion: Esta funcion la utilizo para eliminar el nodo
que se encuentra al principio de la lista.
51 Entradas: Recibe como parametro la lista tipo Punto*.
52 Salidas: Regresa 1 si se pudo eliminar el nodo.*/
53 int EliminarXALSE(Punto *H);
54

55 /*Nombre de la funcion: EliminarXATLSE


56 Descripcion de la funcion: Esta funcion la utilizo para eliminar el nodo
que se encuentra al final de la lista.
57 Entradas: Recibe como parametro la lista tipo Punto*.
58 Salidas: Regresa 1 si se pudo eliminar el nodo.*/
59 int EliminarXATLSE(Punto *H);
60

61 /*Nombre de la funcion: ListarLSE


62 Descripcion de la funcion: Esta funcion la utilizo para imprimir la
lista.
63 Entradas: Recibe como parametro la lista tipo Punto*.
64 Salidas: Como es tipo void no regresa nada pero si imprime*/
65 void ListarLSE(Punto *H);
66

67 /*Nombre de la funcion: MMenu


68 Descripcion de la funcion: Esta funcion la utilizo para imprimir un Menu
con una serie de opciones y asi escanear la accion que quiere hacer
el usuario y llevarla a cabo.
69 Entradas: No recibe ningun parametro.
70 Salidas: Como la funcion es tipo void no regresa nada pero imprime el
menu.*/
71 char MMenu();
72

73

74 int main()
75 {
76 //Creamos la lista
77 //Head = CreaLSE();

21
78

79 //Punto item2, item3, item4;


80 //int X, Y;
81

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

100 while(Res != ’H’){


101

102 M = MMenu();
103 scanf("\n%c", &Res);
104

105 switch(Res){
106

107 case ’A’:


108

109 printf("\na\n");
110

111 if( Head != 0){


112

113 printf("\nNo se puede crear otra lista si ya existe una.


Elimine la Lista creada primero");
114

115 }else{
116

117 Head = CreaLSE();


118 }
119

120 break;
121

122 case ’B’:


123

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

131 Punto item;


132 CapturaN(&item);
133 AddFirst(Head, item);
134 }
135

136 break;
137

138 case ’C’:


139

140 printf("\nc\n");
141 if(Head == 0){
142

143 printf("\nTiene que crear la lista primero para Insertar\n");


144

145 }else{
146

147 Punto item;


148 CapturaN(&item);
149 AddLast(Head, item);
150 }
151

152 break;
153

154 case ’D’:


155

156 printf("\nd\n");
157 //Si no se creo la lista
158 if(Head == 0){
159

160 printf("\nTiene que crear la lista primero para\n");


161

162 }
163

164 if(Head->sig == Tail){


165

166 printf("\nNo se puede eliminar porque la lista esta


vacia\n");
167

168 }else{
169

170 //Si tiene elementos


171

172 int X;
173 X = EliminarXALSE(Head);
174

23
175 }
176

177 break;
178

179 case ’E’:


180

181 printf("\ne\n");
182 //Si no se creo la lista
183 if(Head == 0){
184

185 printf("\nTiene que crear la lista primero para\n");


186

187 }
188

189

190 if(Head->sig == Tail){


191

192 printf("\nNo se puede eliminar porque la lista esta


vacia\n");
193

194 }else{
195

196 //Si tiene elementos


197

198 int X;
199 X = EliminarXATLSE(Head);
200

201 }
202

203 break;
204

205 case ’F’:


206 printf("\nf\n");
207

208 if(Head != 0){


209

210 ListarLSE(Head);
211

212 }
213

214 break;
215

216 case ’G’:


217

218 printf("\ng\n");
219 if(Head != 0){
220

221 EliminarLSE(Head);
222

223 }

24
224

225 break;
226

227 case ’H’:


228 printf("\nSaliendo...\n");
229 break;
230

231 default:
232 printf("\nOpcion invalida seleccione una opcion existente");
233 break;
234 }
235 }
236

237

238

239 return 0;
240 }
241

242

243

244 char MMenu(){


245

246 char RES;


247 printf("\n==========================================================\n");
248 printf("|| LISTAS SIMPLES ||\n");
249 printf("|| Por Diana Aimee Gutierrez May ||\n");
250 printf("===========================================================\n");
251 printf("\nSeleccione una opcion del menu:\n");
252 printf("\n [A] Crear lista");
253 printf("\n [B] Insertar por adelante");
254 printf("\n [C] Insertar por atras");
255 printf("\n [D] Eliminar por adelante");
256 printf("\n [E] Eliminar por atras");
257 printf("\n [F] Listar de adelante hacia atras");
258 printf("\n [G] Eliminar lista");
259 printf("\n [H] Salir del Programa \n");
260

261 return RES;


262 }
263

264 //Funcion para Crear la lista


265 Punto *CreaLSE(){
266

267 Head = ((Punto*)malloc(sizeof(Punto)));


268 Tail = ((Punto*)malloc(sizeof(Punto)));
269

270

271 if( (Head = ((Punto*)malloc(sizeof(Punto)))) == 0){


272

273 printf("No hay espacio de memeria para crear la Lista (H)");

25
274 return Head;
275

276 }
277

278 if( (Tail = ((Punto*)malloc(sizeof(Punto)))) == 0){


279

280 printf("No hay espacio de memeria para crear la Lista (T)");


281 free(Head);
282 return Tail;
283

284 }
285

286 Head->sig = Tail;


287 Tail->sig = Tail;
288

289 return Head;


290

291 }
292

293 void CapturaN(Punto *P){


294

295 printf("\nIngrese X: ");


296 scanf("\n%u\n",&P->X);
297 printf("\n%u\n", P->X);
298

299 printf("\nIngrese Y: ");


300 scanf("\n%u", &P->Y);
301 printf("\n%u\n", P->Y);
302

303 printf("\nIngrese el Color: ");


304 scanf("\n%s", &P->Color);
305 printf("\n%s\n", P->Color);
306

307

308 }
309

310 void AddFirst(Punto *H, Punto Nodo){


311

312 Punto *apP = H;


313 Punto *NewNodo = 0;
314

315 NewNodo = (Punto*)malloc(sizeof(Punto));


316

317

318 if(apP->sig != Tail ){


319

320 *NewNodo = Nodo;


321 NewNodo->sig = H->sig;
322 apP->sig = NewNodo;
323

26
324 }
325

326 else{
327

328 *NewNodo = Nodo;


329 NewNodo->sig = Tail;
330 apP->sig = NewNodo;
331

332

333 }
334

335 return;
336

337 }
338

339 void AddLast(Punto *H, Punto Nodo){


340

341 //Inicializacion
342 Punto *apP = H;
343 Punto *aux = H->sig;
344 Punto *NewNodo = 0;
345

346 NewNodo = (Punto*)malloc(sizeof(Punto));


347

348 //Para recorrerme uno antes de Tail


349 while(apP->sig->sig != aux){
350

351 aux = aux->sig;


352 apP = apP->sig;
353

354 }
355

356 apP->sig = NewNodo;


357 *NewNodo = Nodo;
358 NewNodo->sig = aux;
359

360 return;
361

362 }
363

364

365 int EliminarXALSE(Punto *H){


366

367 Punto *apP = H;


368 Punto *aux1 = H->sig;
369 Punto *aux2 = aux1->sig;
370

371 //Si esta vacia


372 if(aux1->sig == Tail){
373

27
374 printf("\nNo se puede eliminar elemento porque la lista esta
vacia\n");
375

376 return 0;
377

378 }else{
379

380 apP->sig = aux2;


381 free(aux1);
382

383 }
384

385 return 1;
386 }
387

388 int EliminarXATLSE(Punto *H){


389

390 Punto *apP = H;


391 Punto *aux1 = H->sig;
392

393 if(aux1->sig == Tail){


394

395 printf("\nNo se puede eliminar elemento porque la lista esta


vacia\n");
396

397 return 0;
398

399 }
400

401 while(apP->sig->sig != Tail){


402

403 aux1 = aux1->sig;


404 apP = apP->sig;
405

406 }
407

408 apP->sig = Tail;


409 free(aux1);
410 }
411

412

413 void ListarLSE(Punto *H){


414

415 Punto *apP = H;


416 Punto *aux = Tail;
417

418 printf("\n\n");
419

420 while(apP->sig != aux){


421

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

430 void EliminarLSE(Punto *H){


431

432 Punto *apP = H;


433 Punto *aux = 0;
434

435 while(apP->sig != Tail){


436

437 aux = apP->sig;


438 }
439

440 if(aux == Tail){


441 apP->sig = Tail;
442 free(aux);
443

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.

Figure 6: Esquema de un nodo y una lista doblemente enlazada.

2.2.1 Descripción de Programa


El objetivo del código es crear una estructura muy parecida a la que la Proteı́na
maneja medinate dos tipos de TDA.

El primero es una lista doblemente enlazada, la cual se representa por la Ca-


dena de aminoácidos que puede tener una proteı́na pero cada aminoácido puede
almacenar una cadena de átomos lo que quierede decir que es ahı́ donde mane-
jamos el segundo TDA que son las listas simplemente enlazadas.

El programa realizado consta de un menú para realizar cada función y para


poder usarlo presentaré una breve explicación de como manejar el menú.

(b) Composición del Aminoácido

(a) Estructura de la Proteı́na

Figure 7: Comportamiento de la Proteı́na

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

Listing 4: Programa en C para crear una estructura muy parecida a la que la


Proteı́na maneja medinate dos tipos de TDA
1 #include <stdio.h>
2 #include <memory.h>
3 #include <string.h>
4 #include <stdlib.h>
5

6 //Estructura de la lista doblemente Enlazada (Aminoacido)


7 typedef struct AMILDE {
8

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

19 //Estructura de la lista simplemente enlazada (Atomo)


20 typedef struct AtLSE{
21

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

37 /*Nombre de la funcion: MMenu


38 Descripcion de la funcion: Esta funcion la utilizo para desplegar un
menu al usuario y asi realizar diferenntes acciones. Se utliza en
el main para escanear la opcion del usuario y poder realizarla.
39 Entradas: No recibe parametros.*.
40 Salidas: Como la funcion es tipo char, regresa la letra que esocgio el
usuario.*/
41 char MMenu();
42

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

49 /*Nombre de la funcion: CapturaA


50 Descripcion de la funcion: Esta funcion la utilizo para capturar un Nodo
de la lista doble y copiar sus valores en los campos
correspondientes del Nodo.
51 Entradas: Recibe como parametro una variable tipo AMILDE* que es el
nuevo elemento y asi poder utilizarlo despues para agregarlo.
52 Salidas: Como es tipo void no regresa nada pero lleva a cabo la
capturacion del Nodo correctamente.*/
53 void CapturaA(AMILDE *A);
54

55 /*Nombre de la funcion: ImprimeAminoacido


56 Descripcion de la funcion: Esta funcion la utilizo para imprimir el
contenido de un Aminocido.
57 Entradas: Recibe como parametro el nodo tipo AMILIDE* y asi poder
imprimir su contenido.
58 Salidas: Como la funcion es tipo void no regresa nada, solo imprime.*/
59 void ImprimeAminoacido(AMILDE *Nodo);
60

61 /*Nombre de la funcion: AddxOrdLDE


62 Descripcion de la funcion: Esta funcion se usa para recorrer toda la
lista y comparar entre el NS de los nodo para asi agregar el nodo
en orden.
63 Entradas: Recibe una variable tipo AMILDE* (La Lista DOBLE) y el nuevo
elemento tipo AMILDE.
64 Salidas: Regresa 1 si el nodo se pudo agregar a la lista*/
65 int AddxOrdLDE(AMILDE *H, AMILDE *T, AMILDE Nodo);
66

67 /*Nombre de la funcion: ListarLDE_ADAT


68 Descripcion de la funcion: Esta funcion se usa para recorrer toda la
lista de adelante hacia atras e ir imprimiendo los Nodos.
69 Entradas: Recibe como parametro 2 variables tipo AMILDE* que son Head y
Tail para poder recorrer la lista doble.
70 Salidas: Como es tipo void no regresa nada, solo imprime.*/
71 void ListarLDE_ADAT(AMILDE *H, AMILDE *T);
72

73 /*Nombre de la funcion: ListarLDE_ATAD


74 Descripcion de la funcion: Esta funcion se usa para recorrer toda la
lista de atras hacia adelante e ir imprimiendo los Nodos.
75 Entradas: Recibe como parametro 2 variables tipo AMILDE* que son Head y
Tail para poder recorrer la lista doble.
76 Salidas: Como es tipo void no regresa nada, solo imprime.*/

39
77 void ListarLDE_ATAD(AMILDE *H, AMILDE *T);
78

79 /*Nombre de la funcion: FindNumSEC


80 Descripcion de la funcion: Esta funcion se usa para pedirle al usuario
el NumSec a buscar en la lista doble.
81 Entradas: No recibe nungun parametro.
82 Salidas: Como es tipo unsigned, regresa el NumsSEC a buscar.*/
83 unsigned FindNumSEC();
84

85 /*Nombre de la funcion: NumSECFind


86 Descripcion de la funcion: Esta funcion se usa para recorrer toda la
lista doble en busca del NumSec.
87 Entradas: Recibe como parametro una variable tipo unsigned que es el
NumSec.
88 Salidas: Como es tipo int, regresa 0 si encontro coincidencia.*/
89 int NumSECFind(unsigned NUM);
90

91 /*Nombre de la funcion: EliminarXALDE


92 Descripcion de la funcion: Esta funcion la utilizo para eliminar el nodo
que se encuentra al principio de la lista doble.
93 Entradas: Recibe como parametro 2 variables tipo AMILDE*, que son Head y
Tail de la lista.
94 Salidas: Regresa 1 si se pudo eliminar el nodo.*/
95 int EliminarXALDE(AMILDE *H, AMILDE *T);
96

97 /*Nombre de la funcion: EliminarXATLDE


98 Descripcion de la funcion: Esta funcion la utilizo para eliminar el nodo
que se encuentra al final de la lista doble.
99 Entradas: Recibe como parametro 2 variables tipo AMILDE*, que son Head y
Tail de la lista.
100 Salidas: Regresa 1 si se pudo eliminar el nodo.*/
101 int EliminarXATLDE(AMILDE *H, AMILDE *T);
102

103 /*Nombre de la funcion: QueryNumSEC


104 Descripcion de la funcion: Esta funcion se usa para recorrer la lista en
busca de un nodo en especifico y poder imprimir su informacion.
105 Entradas: Recibe como parametro 2 variables tipo AMILDE* que son Head y
Tail (La Lista doble).
106 Salidas: Como la funcion es tipo AMILDE regresa el nodo encontrado.*/
107 AMILDE *QueryNumSEC(AMILDE *H, AMILDE *T);
108

109 /*Nombre de la funcion: ImprimeSearch


110 Descripcion de la funcion: Esta funcion se usa para imprimir el
contenido de un nodo de la lista doble.
111 Entradas: Recibe como parametro el Nodo tipo AMILDE*.
112 Salidas: Como es tipo void no regresa nada, solo imprime.*/
113 void ImprimeSearch(AMILDE *Nodo);
114

115 /*Nombre de la funcion: ModificarA

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

121 /*Zona de Prototipos de la LSE*/


122

123 /*Nombre de la funcion: CreaLSE


124 Descripcion de la funcion: Hace la conexion entre Head y Tail (Variables
globales) y les da espacio de memoria tipo Punto. Para asi usar la
lista vacia.
125 Entradas: No recibe entradas.
126 Salidas: Como la funcion es tipo Punto, regresa a Head para utilizarla
como lista.*/
127 int CreaLSE(AMILDE *Nodo);
128

129 /*Nombre de la funcion: CapturaAt


130 Descripcion de la funcion: Recibe las entradas del usuario para
almacenarlas en un Nodo y asi poder agregarlo a la lista.
131 Entradas: Recibe una variable tipo AtLSE, para copiarlo los valores en
el Nodo.
132 Salidas: Como la funcion es tipo void no tiene salida, pero la variable
que se metio por parametro para Capturar el Nodo se uso, esa es la
que utilizamos.*/
133 void CapturaAt(AtLSE *At);
134

135 /*Nombre de la funcion: ImprimeAt


136 Descripcion de la funcion: Esta funcion se usa para imprimir la
informacion de un nodo que se busca.
137 Entradas: Recibe una variable tipo AtLSE* (La Lista simple).
138 Salidas: Como la funcion es tipo void no tiene salida, pero imprime el
nodo*/
139 void ImprimeAt(AtLSE *NodoAt);
140

141 /*Nombre de la funcion: AddxOrdLSE


142 Descripcion de la funcion: Esta funcion se usa para recorrer toda la
lista y comparar entre el NS de los nodo para asi agregar el nodo
en orden.
143 Entradas: Recibe una variable tipo AtLSE* (La Lista simple) y el nuevo
elemento tipo AtLSE.
144 Salidas: Regresa 1 si el nodo se pudo agregar a la lista*/
145 int AddxOrdLSE(AtLSE *H, AtLSE NodoAt);
146

147 /*Nombre de la funcion: ListarLSE


148 Descripcion de la funcion: Esta funcion se usa para recorrer la lista e
imprimir los nodos.

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

153 /*Nombre de la funcion: FindNS


154 Descripcion de la funcion: Esta funcion se usa para pedirle el NS a
buscar y asi poder imprimir su informacion.
155 Entradas: No recibe ningun parametro.
156 Salidas: Como la funcion es tipo void no tiene salida, pero encuentra el
NS y esta funcion se realiza dentro de la funcion Query para
encontrar el nodo.*/
157 unsigned FindNS();
158

159 /*Nombre de la funcion: ImprimeSearchAT


160 Descripcion de la funcion: Esta funcion se usa para imprimir la
informacion de un nodo de la lista.
161 Entradas: Recibe una variable tipo AtLSE* (La Lista simple).
162 Salidas: Como la funcion es tipo void no tiene salida, pero imprime la
informacion del nodo.*/
163 void ImprimeSearchAT(AtLSE *Nodo);
164

165 /*Nombre de la funcion: QueryNS


166 Descripcion de la funcion: Esta funcion se usa para recorrer la lista en
busca de un nodo en especifico y poder imprimir su informacion.
167 Entradas: Recibe una variable tipo AtLSE* (La Lista simple).
168 Salidas: Como la funcion es tipo AtLSE regresa el nodo encontrado.*/
169 AtLSE *QueryNS(AtLSE *H);
170

171 /*Nombre de la funcion: EliminarXALSE


172 Descripcion de la funcion: Esta funcion la utilizo para eliminar el nodo
que se encuentra al principio de la lista.
173 Entradas: Recibe como parametro la lista tipo AtLSE.*.
174 Salidas: Regresa 1 si se pudo eliminar el nodo.*/
175 int EliminarXALSE(AtLSE *H);
176

177 /*Nombre de la funcion: EliminarXATLSE


178 Descripcion de la funcion: Esta funcion la utilizo para eliminar el nodo
que se encuentra al final de la lista.
179 Entradas: Recibe como parametro la lista tipo AtLSE.*.
180 Salidas: Regresa 1 si se pudo eliminar el nodo.*/
181 int EliminarXATLSE(AtLSE *H);
182

183 /*Nombre de la funcion: ModAT


184 Descripcion de la funcion: Esta funcion la utilizo para modificra un
Atomo de la lista, se le pide al usuario el Atomo a modificar y que
desea modificar. Realiza la busqueda del Atomo y lo modifica.
185 Entradas: Recibe como parametro la lista tipo AtLSE.*.
186 Salidas: Como la funcion es tipo void no regresa nada, pero se modifica
el Atomo.*/

42
187 void ModAT(AtLSE *H);
188

189 /*Nombre de la funcion: Main


190 Descripcion de la funcion: Esta funcion la utilizo para desplegar el
menu y realizar todas las opciones.
191 Entradas: No recibe parametros.
192 Salidas: Realiza todas las opciones.*/
193 int main(){
194

195 char M, Res;


196 int Inser;
197 int InserAt;
198 int Elim;
199 int ElimAt;
200 int Crea;
201 AMILDE item;
202 AtLSE AiTem;
203 AMILDE *QUE = 0;
204 AtLSE *HT = 0;
205 AtLSE *QUEAT = 0;
206 AMILDE NODO;
207 AMILDE NodAT;
208

209

210 while(Res != ’Z’){


211

212 M = MMenu();
213 scanf("\n%c\n", &Res);
214

215 switch(Res){
216

217 case ’A’:


218

219 if( Head != 0){


220

221 printf("\nNo se puede crear otra lista si ya existe


una. Elimine la Lista creada primero");
222

223 }else{
224

225 CreaLDE(&Head, &Tail);


226 }
227

228 break;
229

230

231 case ’B’:


232

233 CapturaA(&item);
234 printf("\n\n\n");

43
235 Inser = AddxOrdLDE(Head, Tail, item);
236 printf("\n\n\n");
237

238 break;
239

240 case ’C’:


241

242 ListarLDE_ADAT(Head, Tail);


243 printf("\n\n\n");
244

245 break;
246

247 case ’D’:


248

249 ListarLDE_ATAD(Head,Tail);
250 printf("\n\n\n");
251

252 break;
253

254 case ’E’:


255

256 QUE = QueryNumSEC(Head, Tail);


257

258 break;
259

260 case ’F’:


261

262 ModificarA();
263

264 break;
265

266 case ’G’:


267

268 Elim = EliminarXALDE(Head, Tail);


269

270 break;
271

272 case ’H’:


273

274 Elim = EliminarXATLDE(Head, Tail);


275

276 break;
277

278 case ’I’:


279

280 printf("\nInserte el Numero Secuencial del Aminoacido en


el cual creara la LSE.\n");
281 QUE = QueryNumSEC(Head, Tail);
282 Crea = CreaLSE(QUE);
283

44
284 if( Crea == 0){
285

286 printf("\nNo se pudo crear la Lista.\n");


287

288 }else{
289

290 printf("\nSe ha creado la lista.\n");


291 }
292

293 break;
294

295

296 case ’J’:


297

298 printf("\nInserte el Numero Secuencial del Aminoacido en


el cual se agregaran Atomos");
299 QUE = QueryNumSEC(Head, Tail);
300 NODO = *(QUE);
301

302 if(NODO.H1 == 0 ){
303

304 printf("\nNo se ha creado la LSE, seleccione I para


crearla y despues regrese.\n");
305

306 }else{
307

308 printf("\nSe ha creado la lista.\n");


309 printf("\nCapturacion del Atomo:\n");
310 CapturaAt(&AiTem);
311 InserAt = AddxOrdLSE(QUE->H1, AiTem);
312 }
313

314

315 break;
316

317

318 case ’K’:


319

320 printf("\nInserte el Numero Secuencial del Aminoacido


para imprimir su lista de Atomos:");
321 QUE = QueryNumSEC(Head, Tail);
322 NODO = *(QUE);
323

324 if(NODO.H1 == 0 ){
325

326 printf("\nNo se ha creado la LSE, seleccione I para


crearla y despues regrese.\n");
327

328 }else{
329

45
330 ListarLSE(NODO.H1);
331

332 }
333

334 break;
335

336

337 case ’L’:


338

339 printf("\nPara buscar el Atomo necesitamos saber a que


Aminoacido corresponde.\n");
340 QUE = QueryNumSEC(Head, Tail);
341 NODO = *(QUE);
342

343 if(NODO.H1 == 0){


344

345 printf("\nNo se ha creado la LSE, seleccione I para


crearla y despues regrese.\n");
346

347 }else{
348

349 QUEAT = QueryNS(NODO.H1);


350

351 }
352

353 break;
354

355

356

357 case ’M’:


358

359 printf("\nPara Eliminar Atomo (Por delante) de LSE,


necesitamos saber a que Aminoacido corresponde.\n");
360 QUE = QueryNumSEC(Head, Tail);
361 NODO = *(QUE);
362

363 if(NODO.H1 == 0){


364

365 printf("\nNo se ha creado la LSE, seleccione I para


crearla y despues regrese.\n");
366

367 }else{
368

369 ElimAt = EliminarXALSE(NODO.H1);


370

371 }
372

373 break;
374

375 case ’N’:

46
376

377 printf("\nPara Eliminar Atomo (Por delante) de LSE,


necesitamos saber a que Aminoacido corresponde.\n");
378 QUE = QueryNumSEC(Head, Tail);
379 NODO = *(QUE);
380

381 if(NODO.H1 == 0){


382

383 printf("\nNo se ha creado la LSE, seleccione I para


crearla y despues regrese.\n");
384

385 }else{
386

387 ElimAt = EliminarXATLSE(NODO.H1);


388

389 }
390

391 break;
392

393

394 case ’Z’:


395 printf("\nSaliendo del Programa.\n");
396 break;
397

398 default:
399 printf("\nOpcion invalida seleccione una opcion existente");
400 break;
401

402 }
403 }
404

405

406 return 0;
407 }
408

409 //Funcion para el Menu


410 char MMenu(){
411

412 char RES;


413 printf("\n==========================================================\n");
414 printf("|| LISTAS DOBLES DE AMINOCIDOS CON ATOMOS (LSE) ||\n");
415 printf("|| Por Diana Aimee Gutierrez May ||\n");
416 printf("===========================================================\n");
417 printf("\nSeleccione una opcion del menu:\n");
418 printf("\n [A] Crear Lista DE");
419 printf("\n [B] Insertar por Orden (Aminoacidos) en LDE");
420 printf("\n [C] Imprimir Lista DE (Adelante hacia atras)");
421 printf("\n [D] Imprimir Lista DE (Atras hacia delante)");
422 printf("\n [E] Buscar un Aminoacido en LDE");
423 printf("\n [F] Modificar Aminoacido");

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

434 return RES;


435 }
436

437 /*FUNCIONES PARA LA LISTA DOBLEMENTE ENLAZADA*/


438

439 //Funcion para crear la LDE FUNCIONA


440 void CreaLDE(AMILDE **H, AMILDE **T){
441

442 //Variables auxiliares


443 AMILDE *Head1;
444 AMILDE *Tail1;
445

446 //Asignacion de memoria


447 Head1 = ((AMILDE*)malloc(sizeof(AMILDE)));
448 Tail1 = ((AMILDE*)malloc(sizeof(AMILDE)));
449

450 //Verificacion de memoria


451 if(Head1 == 0 || Tail1 == 0){
452

453 printf("\nNo hay memoria.\n");


454 return;
455

456 }
457

458 //Union a si mismos


459 Head1->prev = Head1;
460 Tail1->next = Tail1;
461

462 //Union entre ellos mismos


463 Tail1->prev = Head1;
464 Head1->next = Tail1;
465

466 *(H) = Head1;


467 *(T) = Tail1;
468

469 return;
470 }
471

472 //Funcion para capturar los Aminoacidos


473 void CapturaA(AMILDE *A){

48
474

475 int NS;


476

477 printf("\nIngrese el Numero de secuencia del Aminoacido: ");


478 scanf("\n%u\n", &A->NumSEC);
479 printf("\n%u\n", A->NumSEC);
480

481 NS = NumSECFind(A->NumSEC);
482 if (NS == 0){
483

484 printf("\nIngrese otro Numero secuencial: ");


485 scanf("\n%u\n", &A->NumSEC);
486 printf("\n%u\n", A->NumSEC);
487

488 }
489

490 printf("\nIngrese un caracter alfabetico para la Cadena: ");


491 scanf("\n%c\n", &A->Cadena);
492 printf("\n%c\n", A->Cadena);
493

494 printf("\nIngrese el Nombre del Aminoacido: ");


495 scanf("\n%s\n", &A->Nombre);
496 printf("\n%s\n", A->Nombre);
497

498 printf("\nIngrese el Coeficiente de Particion del Aminoacido: ");


499 scanf("\n%f\n", &A->KOW);
500 printf("\n%.2f\n", A->KOW);
501

502 return;
503 }
504

505 //Numero secuencial unico


506 int NumSECFind(unsigned NUM){
507

508 AMILDE *apA = Head;


509

510 //Si la lista esta vacia


511 if( apA->next == Tail){
512

513 printf("\nLa lista esta vacia, por lo que se puede agregar el


Nodo\n");
514

515 return 1;
516 }
517

518 if (apA->next != Tail){


519

520 //Para recorrernos mientras comparamos


521 while(apA->next->NumSEC <= NUM ){
522

49
523 apA = apA->next;
524

525 return 0;
526

527 }
528

529 }
530

531 }
532

533 //Funcion para Imprimir los Aminoacidos


534 void ImprimeAminoacido(AMILDE *Nodo){
535

536 printf("\nInformacion del Aminoacido:");


537 printf("\nNombre: %s", Nodo->Nombre);
538 printf("\nNumero Secuencial: %u", Nodo->NumSEC);
539 printf("\nCadena: %c", Nodo->Cadena);
540 printf("\nCoeficiente de particion: %.2f", Nodo->KOW);
541 printf("\n\t| ^");
542 printf("\n\t| |");
543 printf("\n\t| |");
544 printf("\n\t| |");
545 printf("\n\tV |");
546

547 return;
548 }
549

550 //Funcion para Imprimir el Aminoacido Buscado


551 void ImprimeSearch(AMILDE *Nodo){
552

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

563 //Funcion para Insertar por Orden en la Lista Doblemente Enlazada


564 int AddxOrdLDE(AMILDE *H, AMILDE *T, AMILDE Nodo){
565

566 //Variables auxiliares


567 AMILDE *apA = H;
568 AMILDE *NewNodo = 0;
569

570 //Asignacion de memoria


571 NewNodo = ((AMILDE*)malloc(sizeof(AMILDE)));
572

50
573 //Verificacin de Memoria
574 if( (NewNodo = ((AMILDE*)malloc(sizeof(AMILDE)))) == 0){
575

576 return 0;
577 }
578

579 //Si no esta vacia


580 while(apA->next != Tail && Nodo.NumSEC > apA->next->NumSEC){
581

582 apA = apA->next;


583 }
584

585 //Guardamos lo que contenga Nodo a NewNodo


586 *(NewNodo) = Nodo;
587

588 //Conectamos los Nodos


589 NewNodo->prev = apA;
590 NewNodo->next = apA->next;
591 apA->next = NewNodo;
592 NewNodo->next->prev = NewNodo;
593

594 return 1;
595

596 }
597

598 //Funcion para extraer por adelante LDE


599 int EliminarXALDE(AMILDE *H, AMILDE *T){
600

601 AMILDE *apA = H;


602 AMILDE *aux1 = H->next;
603 AMILDE *aux2 = aux1->next;
604

605 //Si esta vacia


606 if (aux1 == T && aux2 == T){
607

608 printf("\nNo se puede eliminar porque la lista esta vacia\n");


609

610 return 0;
611

612 //Si no esta vacia


613 }else{
614

615 //Reconceccion de Nodos


616 apA->next = aux2;
617 aux2->prev = apA;
618 free(aux1);
619 }
620

621 return 1;
622 }

51
623

624 //Funcion para extraer por atras LDE


625 int EliminarXATLDE(AMILDE *H, AMILDE *T){
626

627 AMILDE *apA = H;


628 AMILDE *aux1 = H->next;
629 AMILDE *aux2 = aux1->next;
630

631 //Si esta vacia


632 if (aux1 == T && aux2 == T){
633

634 printf("\nNo se puede eliminar porque la lista esta vacia\n");


635

636 return 0;
637

638 }
639

640 while(apA->next->next != T){


641

642 aux1 = aux1->next;


643 apA = apA->next;
644 }
645

646 //Reconecion de Nodos


647 apA->next = T;
648 T->prev = apA;
649 free(aux1);
650

651 }
652

653 //Funcion para Listar LDE (Adelante hacia antras)


654 void ListarLDE_ADAT(AMILDE *H, AMILDE *T){
655

656 // Inicializacion de las variables auxiliares.


657 AMILDE *apA;
658

659 // Si la lista esta vacia, se sale de la funcion.


660 if (H->next == T && T->prev == H)
661 {
662 printf("\nLa lista esta vacia.\n");
663 return;
664 }
665

666 // El apuntador inicial toma la posicion del primer elemento de la


lista.
667 apA = H->next;
668

669 // Ciclo que imprime la informacion de cada Aminoacido en la lista.


670 while (apA->next != apA)
671 {

52
672 ImprimeAminoacido(apA);
673

674 //Desplazamiento del apuntador a la posicion siguiente.


675 apA = apA->next;
676 }
677

678 return;
679 }
680

681 //Funcion para Listar LDE (Atras hacia adelante)


682 void ListarLDE_ATAD(AMILDE *H, AMILDE *T){
683

684 // Inicializacion de las variables auxiliares.


685 unsigned Contador = 1;
686 AMILDE *apA;
687

688 // Si la lista esta vacia, se sale de la funcion.


689 if (H->next == T && T->prev == H)
690 {
691 printf("\nLa lista esta vacia.\n");
692 return;
693 }
694

695 // El apuntador inicial toma la posicion del primer elemento de la


lista.
696 apA = T->prev;
697

698 // Ciclo que imprime la informacion de cada Aminoacido en la lista.


699 while (apA->prev != apA)
700 {
701 printf("\nNumero de Nodo agregado: %u", Contador);
702 ImprimeAminoacido(apA);
703

704 // Aumento del contador, y desplazamiento del apuntador a la


posicion siguiente.
705 Contador++;
706 apA = apA->prev;
707 }
708

709 return;
710 }
711

712 //Funcion para pedirle el NumSEC a buscar


713 unsigned FindNumSEC(){
714

715 unsigned SEC;


716

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

722 return SEC;


723 }
724

725 //Funcion para Consultar Aminoacidos, permite realizar la busqueda por


NumSEC en LDE
726 AMILDE *QueryNumSEC(AMILDE *H, AMILDE *T){
727

728 AMILDE *apA = H->next;


729 AMILDE *aux = 0;
730

731 //Se verifica que la lista no esta vacia


732 if ( H->next == T && T->prev == H){
733

734 printf("\nLa lista esta vacia.\n");


735

736 return 0;
737 }
738

739 //Guardamos el Numero en N


740 unsigned N;
741 N = FindNumSEC();
742

743 //Proceso para recorrer y comparar


744 while (apA != T){
745

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

758 apA = apA->next;


759

760 }
761

762 printf("\nNo se encontro un elemento en comun.\n");


763 return 0;
764 }
765

766 //Funcion para modificar un Nodo

54
767 void ModificarA(){
768

769

770 AMILDE *Q = 0;
771 //unsigned N = 9;
772 int M;
773

774 Q = QueryNumSEC(Head, Tail);


775

776 do{
777

778 printf("\nSeleccione lo que desea modificar del Aminoacido:\n");


779 printf("1. Modificar su Numero Secuencial.\n");
780 printf("2. Modificar el caracter de la Cadena.\n");
781 printf("3. Modificar su Nombre.\n");
782 printf("4. Modificar su Coeficiennte de Particion.\n");
783 printf("0. Para Salir.");
784 printf("\nEscriba la opcion: \n");
785 scanf("\n%d\n", &M);
786

787 switch(M){
788

789 case 1:
790

791 printf("\nEscriba el nuevo Numero Secuencial: \n");


792 scanf("\n%u\n", &Q->NumSEC);
793

794 break;
795

796 case 2:
797

798 printf("\nEscriba el nuevo caracter de la Cadena: \n");


799 scanf("\n%s\n", &Q->Cadena);
800

801 break;
802

803 case 3:
804

805 printf("\nEscriba el nuevo Nombre del Aminoacido: \n");


806 scanf("\n%s\n", &Q->Nombre);
807

808 break;
809

810 case 4:
811

812 printf("\nEscriba el nuevo Nombre del Aminoacido: \n");


813 scanf("\n%f\n", &Q->KOW);
814

815 break;
816

55
817

818 case 0:
819

820 printf("\n.Saliendo del Menu Modificar...\n");


821

822 break;
823

824 default:
825 printf("\nOpcion invalida, seleccione otra.\n");
826 break;
827 }
828

829

830 }while(M != 0);


831

832 return;
833 }
834

835 /*FUNCIONES PARA LA LISTA SIMPLEMETE ENLAZADA*/


836

837 //Funcion para crear la LSE


838 int CreaLSE(AMILDE *Nodo){
839

840 //Asignacion de memoria


841 Nodo->H1 = ((AtLSE*)malloc(sizeof(AtLSE)));
842 Tail2 = ((AtLSE*)malloc(sizeof(AtLSE)));
843

844 //Comprobacion de memoria


845 if( (Nodo->H1 = ((AtLSE*)malloc(sizeof(AtLSE)))) == 0){
846

847 printf("No hay espacio de memeria para crear la Lista (H)");


848 return 0;
849

850 }
851

852 if( (Tail2 = ((AtLSE*)malloc(sizeof(AtLSE)))) == 0){


853

854 printf("No hay espacio de memeria para crear la Lista (T)");


855 //Por si no hubo error en H
856 free(Nodo->H1);
857 return 0;
858

859 }
860

861 //Conectamos Head y Tail


862 Nodo->H1->next = Tail2;
863 Tail2->next = Tail2;
864

865 return 1;
866 }

56
867

868 //Funcion para Capturar los Atomos


869 void CapturaAt(AtLSE *At){
870

871 printf("\nIngrese el Numero de secuencia del Atomo: ");


872 scanf("\n%u\n", &At->NS);
873 printf("\n%u\n", At->NS);
874

875 printf("\nIngrese el Nombre del Atomo: ");


876 scanf("\n%s\n", &At->NomAT);
877 printf("\n%s\n", At->NomAT);
878

879 printf("\nIngrese el Coeficiente de Particion del Atomo: ");


880 scanf("\n%f\n", &At->PS);
881 printf("\n%.2f\n", At->PS);
882

883 return;
884 }
885

886 //Funcion para Imprimir los Atomos


887 void ImprimeAt(AtLSE *NodoAt){
888

889 printf("\nInformacion del Aminoacido:");


890 printf("\nNombre: %s", NodoAt->NomAT);
891 printf("\nNumero Secuencial: %u", NodoAt->NS);
892 printf("\nPorcentaje de superficie expuesta: %.2f", NodoAt->PS);
893 printf("\n\t|");
894 printf("\n\t|");
895 printf("\n\t|");
896 printf("\n\t|");
897 printf("\n\tV");
898

899 return;
900 }
901

902 //Funcion para Insertar por Orden en la Lista Simplemente Enlazada


903 int AddxOrdLSE(AtLSE *H, AtLSE NodoAt){
904

905 AtLSE *apAt = H;


906 AtLSE *NewAt = 0;
907 AtLSE *aux = 0;
908

909 //Asignacion de memoria


910 NewAt = ((AtLSE*)malloc(sizeof(AtLSE)));
911

912 //Verificacion de memoria


913 if( (NewAt = ((AtLSE*)malloc(sizeof(AtLSE)))) == 0 ){
914

915 printf("\nNo se pudo crear LSE\n");


916 return 0;

57
917 }
918

919 //Si no esta vacia


920 if(apAt->next != Tail2){
921

922 //NOS RECORREMOS UNA POSICION ANTES


923 while (apAt->next != Tail2 && NodoAt.NS > apAt->next->NS){
924

925 apAt = apAt->next;


926 }
927 }
928

929 //Guardamos lo que tenga el Nodo en NewAt


930 *(NewAt) = NodoAt;
931

932 //Conectamos
933 if(apAt->next == Tail2){
934

935 NewAt->next = Tail2;


936 apAt->next = NewAt;
937

938 }else{
939

940 NewAt->next = apAt->next;


941 apAt->next = NewAt;
942 }
943

944 return 1;
945 }
946

947 //Funcion para imprimir los elementos de la lista


948 void ListarLSE(AtLSE *H){
949

950 AtLSE *apAt = H;


951 AtLSE *aux = Tail2;
952

953 printf("\n\n");
954

955 while(apAt->next != aux){


956

957 printf("(%s-%u):%.2f ->",apAt->next->NomAT, apAt->next->NS,


apAt->next->PS);
958 apAt = apAt->next;
959

960 }
961

962 return;
963 }
964

965 //Funcion para pedirle el NS a buscar

58
966 unsigned FindNS(){
967

968 unsigned SEC;


969

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

975 return SEC;


976 }
977

978 //Funcion para Imprimir el Atomo Buscado


979 void ImprimeSearchAT(AtLSE *Nodo){
980

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

990 //Funcion para Buscar por NS en la LSE


991 AtLSE *QueryNS(AtLSE *H){
992

993 AtLSE *apAT = H->next;


994 AtLSE *aux = 0;
995

996 //Se verifica que la lista no este vacia


997 if ( H->next == Tail2 && Tail2->next == Tail2){
998

999 printf("\nLa lista esta vacia.\n");


1000

1001 return 0;
1002

1003 }
1004

1005 //Guardamos el Numero en N


1006 unsigned N;
1007 N = FindNS();
1008

1009 //Proceso para recorrer y comparar


1010 while (apAT != Tail2){
1011

1012 if ( apAT->NS == N){


1013

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

1021 return apAT;


1022 }
1023

1024 apAT = apAT->next;


1025 }
1026

1027 printf("\nNo se encontro un elemento en comun.\n");


1028

1029 return 0;
1030 }
1031

1032 //Funcion para extraer por adelante LSE


1033 int EliminarXALSE(AtLSE *H){
1034

1035 AtLSE *apAT = H;


1036 AtLSE *aux1 = H->next;
1037 AtLSE *aux2 = aux1->next;
1038

1039 //Si esta vacia


1040 if (aux1 == Tail2 && aux2 == Tail2){
1041

1042 printf("\nNo se puede eliminar porque la lista esta vacia.\n");


1043

1044 return 0;
1045

1046 //Si no esta vacia


1047 }else{
1048

1049 //Reconeccion de Nodos


1050 apAT->next = aux2;
1051 free(aux1);
1052 }
1053

1054 return 1;
1055 }
1056

1057 //Funcion para extraer por atras LSE


1058 int EliminarXATLSE(AtLSE *H){
1059

1060 AMILDE *apAT = H;


1061 AMILDE *aux1 = H->next;
1062 AMILDE *aux2 = aux1->next;
1063

60
1064 //Si esta vacia
1065 if (aux1 == Tail2 && aux2 == Tail2){
1066

1067 printf("\nNo se puede eliminar porque la lista esta vacia\n");


1068

1069 return 0;
1070

1071 }
1072

1073 while(apAT->next->next != Tail2){


1074

1075 aux1 = aux1->next;


1076 apAT = apAT->next;
1077 }
1078

1079 //Reconecion de Nodos


1080 apAT->next = Tail2;
1081 Tail2->next = Tail2;
1082 free(aux1);
1083

1084 return 1;
1085 }
1086

1087 //Funcion para Modificar un Atomo


1088 void ModAT(AtLSE *H){
1089

1090 AtLSE *Q = 0;
1091 int MM;
1092

1093 Q = QueryNS(H);
1094

1095

1096 do{
1097

1098 printf("\nSeleccione lo que desea modificar del Atomo y despues


0 para Salir:\n");
1099 printf("1. Modificar su Numero Secuencial.\n");
1100 printf("2. Modificar su Nombre.\n");
1101 printf("3. Modificar su Porcentaje de Superficie Expuesta.\n");
1102 printf("0. Para Salir.");
1103 printf("\nEscriba la opcion: \n");
1104 scanf("\n%d\n", &MM);
1105

1106 switch(MM){
1107

1108 case 1:
1109

1110 printf("\nEscriba el nuevo numero: ");


1111 scanf("\n%u\n", &Q->NS);
1112

61
1113 break;
1114

1115 case 2:
1116

1117 printf("\nEscriba el nuevo Nombre del Atomo: ");


1118 scanf("\n%s\n", &Q->NomAT);
1119

1120 break;
1121

1122 case 3:
1123

1124 printf("\nEscriba el nuevo Porcentaje de Superficie


Expuesta: ");
1125 scanf("\n%f\n", &Q->PS);
1126

1127 break;
1128

1129

1130 case 0:
1131

1132 printf("\nSaliendo...\n");
1133

1134 break;
1135

1136 default:
1137

1138 printf("\nOpcion invalida, seleccione una opcion


existente");
1139

1140 break;
1141 }
1142

1143 }while(MM != 0);


1144

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.

B Insertar por Orden (Aminoacidos) en LDE Para insertar un aminoácido


empezamos con la capturación de él:
(a) Número secuencial: ’5’
(b) Carácter de la Cadena: ’D’
(c) Nombre del Aminoácido: ’VAL’
(d) Coeficiente de Partición: ’87.95’

Ejemplo:
A
5
D
VAL
87.95

Ya que insertamos nos imprime nuestros valores en pantalla para compro-


bar que sean los correctos.

C Imprimir Lista DE (Adelante hacia atrás)


Al ingresar ’C’ imprime en pantalla los aminoácidos de adelante hacia
atrás. En orden de menor a mayor ya que ası́ se insertan en la lista.

D Imprimir Lista DE (Atrás hacia adelante)


Al ingresar ’D’ imprime en pantalla los aminoácidos atrás hacia adelante.
En orden de mayor a menor ya que ası́ se insertan en la lista.

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.

(a) 1.Modificar su Número Secuencial


(b) 2. Modificar el carácter de la Cadena
(c) 3. Modificar su Nombre
(d) 4. Modificar su Coeficiennte de Partición
(e) 0. Para Salir
Ejemplo:
F
5
1
3
2
R
3
MET
4
9.86
0

G Eliminar Aminoacido (Por Adelante


Para eliminar el primer aminoácido que conforma la lista sólo tiene que
ingresar ’G’.

H Eliminar Aminoacido (Por Atrás


Para eliminar el último aminoácido que conforma la lista sólo tiene que
ingresar ’H’.

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

J Isertar (Átomos) por Orden en LSE


Para insertar átomos ya que se haya creado la lista necesitamos el número
de aminácido.
(a) Número secuencial: ’1’
(b) Nombre del Átomo: ’CA’
(c) Coeficiente de Partición: ’15.65’

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

L Buscar un Átomo de un Aminoacido.


Para buscar un átomo necesitamos el número secuencial del aminoácido en
donde se encuentra el átomo para ello ingresar ’L’, después el Aminoacidos
y al final el Átomo.
Ejemplo:
L
5
1

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

N Eliminar Átomo (Por Atrás).


Para eliminar por atrás necesitamos el aminoácido, ya que lo que pasamos
es la lista simple del aminoácido.
Ejemplo:
M
5

Z Salir del Programa.


Al ingresar diferentes entradas SIEMPRE DEBE DE TERMINAR CON
’Z’ para que el programa pueda cerrarse.

66
2.2.4 Salidas
Explicación de la salida general:

(a) Creación de la lista e insertar


aminoácido

(b) Insertar aminoácido

Figure 8: Creación de la lista doblemente enlazada

67
(b) Listar LDE de adelante hacia atrás

(a) Inserción de aminoácidos

Figure 9: Aminoácidos

68
(b) Salir del programa

(a) Listar LDE de atrás hacia delante

Figure 10: Listar

69
(a) Busqueda de aminoácido

(b) Busqueda de aminoácido

Figure 11: Busqueda de aminoácidos

70
(a) Modificar aminoácido

(b) Listar LDE

Figure 12: Lista de Aminoacidos

71
(b) Creación de LSE de átomos

(a) Eliminación por Adelate y atrás

Figure 13: Aminoacidos

72
(b) Busqueda de Aminoácido
(a) Insertar Átomo

Figure 14: Insertar y busqueda

73
(b) Insertar átomo
(a) Busqueda de átomo

Figure 15: Busqueda e Insertar

74
(a) Insertar átomo

(b) Insertar átomo

Figure 16: Inserción del átomos a la lista

75
(a) Imprimir la lista de átomos del Aminoacido

(b) Salir del programa

Figure 17: Listar LSE

76
(a) Busqueda

(b) Busqueda

Figure 18: Busqueda para Eliminar

77
(a) Por atrás y por adelante

Figure 19: Eliminación de átomos

2.2.5 Link del Programa


Para consulta puede ingresar al siguiente link para verificar el programa: https:
//code.hackerearth.com/bc6556b

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.

Figure 20: Representación de una Tabla Hash

2.3.1 Descripción de Programa


La compañı́a Caribbean Analytics quiere llevar un registro de las menciones
a los candidatos presidenciales de la república mexicana para el año 2018 que
se realizan en algunas páginas web. El seguimiento que se realice permitir
relacionar con mayor certidumbre si estos sitios web establecen alguna tendencia
positiva o negativa para determinado candidato. El diseño que se propone para
resolver este problema se resume en la siguiente figura.

1 Árbol de Transacción: El árbol de transacción almacena: URL, Candidato


y palabra del diccionario.
2 Árbol Dupla: El árbol de Dupla almacena: Candidato, palabra y una
variable que aumente la frecuencia de las menciones de la palbra en ese
candidato.

79
80
2.3.2 Código en C

Listing 5: Programa en C de Politicos .


1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <memory.h>
5

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

24 /*Nombre de la funcion: CreaLSE


25 Descripcion de la funcion: Inicializa la Tabla Hash con su respectivo
tam del Array y sus listas de cada posicion del array conectadas.
26 Entradas: No recibe entradas.
27 Salidas: Como la funcion es tipo int, regresa 1 si se creo la Tabla Hash
correctamente.*/
28 int Init_ArrayLinked();
29

30 int ReadArchive(char *Path);


31

32 /*Nombre de la funcion: ArrayPosition


33 Descripcion de la funcion: Esta funcion la utilizo para que la palabra
que lea del archivo sume todas las letras y realice la operacion
modulo para obtner la key (posicion en que se alojara la palabra en
el Array).
34 Entradas: Recibe una variable tipo char que es lo que lee del archivo.
35 Salidas: Como la funcion es tipo int, regresa la Key.*/
36 int ArrayPosition(char *Palabra);
37

38 /*Nombre de la funcion: AddFirst


39 Descripcion de la funcion: Esta funcion la utilizo para agregar al
principio de la lista un Nodo tipo Nodo.

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

44 /*Nombre de la funcion: Display


45 Descripcion de la funcion: Esta funcion la utilizo para recorrer el
Array e imprimir la lista de cada una de las posiciones.
46 Entradas: No recibe ningun parametro.
47 Salidas: Como la funcion es tipo void no regresa nada pero imprime la
Tabla Hash.*/
48 void Display();
49

50 /*Nombre de la funcion: CapturaCan


51 Descripcion de la funcion: Esta funcion copia la informacion dada a un
nodo tipo Nodo*.
52 Entradas: Recive 2 variables como parametros, una tipo Nodo* que es el
nuevo elemento y una tipo char* que es la informacion que se va a
copiar al nodo.
53 Salidas: Como la funcion es tipo int, regresa 1 si se copio la
informacion correctamente.*/
54 int CapturaCan(Nodo *P, char *Nombre);
55

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

86 /*Zona de prototipos del Arbol de Transaccion*/


87 int Suma_ASCII(char *url, char *c, char *w);
88

89 /*Nombre de la funcion: CreaNodoAT


90 Descripcion de la funcion: Esta funcion la utilizo para crear cada nodo
que se agregara al arbol en orden.
91 Entradas: Recibe como parametros 3 variables tipo char el URL, Candidato
y la palabra para copiarlos al Nodo creado y una variable tipo int
que es la key.
92 Salidas: Como la funcion es tipo Nodo_AT regrasa el Nodo creado para
poder insertarlo en el arbol.*/
93 Nodo_AT *CreaNodoAT(char *url, char *candidato, char *word, int ascii);
94

95 /*Nombre de la funcion: InserNAT


96 Descripcion de la funcion: Esta funcion la utilizo para agregar al arbol.
97 Entradas: Recibe como parametro el arbol y el nuevo elemento a agregar.
98 Salidas: Como la funcion es tipo void no regresa nada pero agrega al
arbol en orden*/
99 void InserNAT(Nodo_AT *R, Nodo_AT *Item);
100

101 /*Nombre de la funcion: R_PRE


102 Descripcion de la funcion: Esta funcion la utilizo para recorrer el
arbol en Preorden e ir impriemiendo cada Nodo.
103 Entradas: Recibe como parametro el arbol tipo Nodo_AT.
104 Salidas: Como la funcion es tipo void no regresa nada pero imprime en
Preorden.*/
105 void R_PRE(Nodo_AT *R);
106

107 /*Nombre de la funcion: R_INOR


108 Descripcion de la funcion: Esta funcion la utilizo para recorrer el
arbol en Inorden e ir impriemiendo cada Nodo.
109 Entradas: Recibe como parametro el arbol tipo Nodo_AT.
110 Salidas: Como la funcion es tipo void no regresa nada pero imprime en
Inorden.*/
111 void R_INOR(Nodo_AT *R);
112

113 /*Nombre de la funcion: R_POSTOR


114 Descripcion de la funcion: Esta funcion la utilizo para recorrer el
arbol en Postorden e ir impriemiendo cada Nodo.
115 Entradas: Recibe como parametro el arbol tipo Nodo_AT.
116 Salidas: Como la funcion es tipo void no regresa nada pero imprime en
Postorden.*/
117 void R_POSTOR(Nodo_AT *R);
118

119 /*Zona de prototipos de Arbol Dupla*/

83
120

121 /*Nombre de la funcion: CreaNodoDu


122 Descripcion de la funcion: Esta funcion la utilizo para crear un nodo
del arbol Dupla.
123 Entradas: Recibe como parametro el arbol 2 variables tipo char,
Candidato y Palabra. Y recibe otra variable tipo int que es el
contador de las repeticiones de la palabra.
124 Salidas: Como la funcion es tipo Nodo_DU, regresa el nodo creado para
asi poder insertarlo al arbol dupla.*/
125 Nodo_DU *CreaNodoDu(char *candidato, char *word, int ascii);
126

127 /*Nombre de la funcion: Suma_ASCIIDU


128 Descripcion de la funcion: Esta funcion la utilizo para calcular la suma
de todos los campos del Nodo y asi poder ordenarlos mejor en el
arbol (mas balanceado).
129 Entradas: Recibe como parametros 2 variables tipo char, Candidato y la
palabra para asi realizar la suma de sus letras.
130 Salidas: Como la funcion es tipo int regresa la suma total.*/
131 int Suma_ASCIIDU(char *c, char *w);
132

133 /*Nombre de la funcion: R_PRE


134 Descripcion de la funcion: Esta funcion la utilizo para insertar en el
arbol dupla de una manera mas balanceada.
135 Entradas: Recibe como parametro el arbol tipo Nodo_DU* y el elemto a
agregar tipo Nodo_DU*.
136 Salidas: Como la funcion es tipo void no regresa nada pero agrega al
arbol dupla.*/
137 void InserNDU(Nodo_DU *R, Nodo_DU *Item);
138

139 /*Nombre de la funcion: PREDU_R


140 Descripcion de la funcion: Esta funcion la utilizo para recorrer el
arbol en Preorden e ir impriemiendo cada Nodo.
141 Entradas: Recibe como parametro el arbol tipo Nodo_DU.
142 Salidas: Como la funcion es tipo void no regresa nada pero imprime en
Preorden.*/
143 void PREDU_R(Nodo_DU *R);
144

145 /*Nombre de la funcion: INORDU_R


146 Descripcion de la funcion: Esta funcion la utilizo para recorrer el
arbol en Inorden e ir impriemiendo cada Nodo.
147 Entradas: Recibe como parametro el arbol tipo Nodo_DU.
148 Salidas: Como la funcion es tipo void no regresa nada pero imprime en
Inorden.*/
149 void INORDU_R(Nodo_DU *R);
150

151 /*Nombre de la funcion: POSTORDU_R


152 Descripcion de la funcion: Esta funcion la utilizo para recorrer el
arbol en Postorden e ir impriemiendo cada Nodo.
153 Entradas: Recibe como parametro el arbol tipo Nodo_DU.

84
154 Salidas: Como la funcion es tipo void no regresa nada pero imprime en
Postorden.*/
155 void POSTORDU_R(Nodo_DU *R);
156

157 /*Estructura de los 4 Arreglos de los candidatos*/


158 typedef struct Candidato{
159

160 char *Nombre;


161 struct Candidato *Next;
162

163 }Candidato;
164

165 /*Variables Globales de las listas de cada candidato*/


166 Candidato *Head_AMLO = 0;
167 Candidato *Tail_AMLO = 0;
168

169 Candidato *Head_Anaya = 0;


170 Candidato *Tail_Anaya = 0;
171

172 Candidato *Head_Meade = 0;


173 Candidato *Tail_Meade = 0;
174

175 Candidato *Head_Zavala = 0;


176 Candidato *Tail_Zavala = 0;
177

178 /*Zona de prototipos de la Lista*/


179

180 /*Nombre de la funcion: CreaLSE, CreaLSE1, CreaLSE2 y CreaLSE3


181 Descripcion de la funcion: Inicializa cada una de las listas de los
candidatos ya que estan se utlizan para alm los nombres u apodos de
ellos.
182 Entradas: No recibe entradas.
183 Salidas: Como la funcion es tipo Candidato, regresa al Head de cada una
de las listas de los Candidatos (Regresa la lista Inicializada).*/
184 Candidato *CreaLSE();
185 Candidato *CreaLSE1();
186 Candidato *CreaLSE2();
187 Candidato *CreaLSE3();
188

189 /*Nombre de la funcion: CapturaCan


190 Descripcion de la funcion: Esta funcion copia la informacion dada a un
nodo tipo Candidato*.
191 Entradas: Recive 2 variables como parametros, una tipo Candidato* que es
el nuevo elemento y una tipo char* que es la informacion que se va
a copiar al nodo.
192 Salidas: Como la funcion es tipo int, regresa 1 si se copio la
informacion correctamente.*/
193 int CapturaCan(Candidato *P, char *Nombre);
194

195 /*Nombre de la funcion: AddFirst

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

201 /*Nombre de la funcion: EliminarXATLSE


202 Descripcion de la funcion: Esta funcion la utilizo para eliminar el nodo
que se encuentra al final de la lista doble.
203 Entradas: Recibe como parametro 2 variables tipo Candidato*, que son
Head y Tail de la lista.
204 Salidas: Regresa 1 si se pudo eliminar el nodo.*/
205 int EliminarXATLSE(Candidato *H, Candidato *T);
206

207 /*Nombre de la funcion: ListarLSE


208 Descripcion de la funcion: Esta funcion la utilizo para imprimir una
lista de los Candidatos.
209 Entradas: Recibe como parametro 2 variables tipo Candidato*, que son
Head y Tail de la lista.
210 Salidas: Como la funcion es tipo void no regresa nada solo imprime.*/
211 void ListarLSE(Candidato *H, Candidato *T);
212

213

214 /*Nombre de la funcion: CreaAMLO, CreaAnaya, CreaMeade y CreaZavala


215 Descripcion de la funcion: Cada una de estas funciones genera
automaticamente la lista con sus respectivos nombres u apodos de
cada candidato para asi ir comparando con los datos de la pagina.
216 Entradas: No recibe entradas.
217 Salidas: Como la funcion es tipo int regresa 1 si se agregaron los nodos
a la lista de cada Candidato.*/
218 int CreaAMLO();
219 int CreaAnaya();
220 int CreaMeade();
221 int CreaZavala();
222

223 int main() {


224

225 int AMLO, Anaya, Meade, Zavala;


226

227 AMLO = CreaAMLO();


228 Anaya = CreaAnaya();
229 Meade = CreaMeade();
230 Zavala = CreaZavala();
231

232 int Arr;


233 char texto[30];
234 int Mod1;
235 char Name[10];

86
236 int RES;
237

238

239 Arr = Init_ArrayLinked();


240 if(Arr == -1){
241

242 printf("\nNo se creo correctamente la Tabla Hash.\n");


243 }
244 else{
245

246 printf("\nSe creo correctamente la Tabla Hash.\n");


247 }
248

249 Nodo P;
250 int CN;
251 char Pa[30] = "DIEGO";
252 int Pos;
253 printf("\n%s", Pa);
254

255 //P = Crea_Nodo(Pa);


256 CN = CapturaCan(&P, Pa);
257 Pos = ArrayPosition(Pa);
258 AddFirst(Array, P, Pos);
259

260 printf("Escribe el nombre del Diccionario (Ejemplo:


Diccionario.txt):\n");
261 scanf("%s", &Name);
262 getchar();
263 printf("%s\n", Name);
264

265 RES = ReadArchive(Name);


266

267

268 /*
269 printf("\nEscriba la palabra:\n");
270 fgets(texto, 30, stdin);
271

272 Mod1 = ArrayPosition(texto);


273 printf("\nEl valor que se regreso es: %d\n", Mod1);
274

275 printf("Escribe el nombre del Diccionario (Ejemplo:


Diccionario.txt):\n");
276 scanf("%s", &Name);
277 getchar();
278 printf("%s\n", Name);
279

280 RES = ReadArchive(Name);


281 */
282 Display();
283

87
284

285 getchar();
286 return 0;
287 }
288

289 //Funcion para capturar el Nodo


290 int CapturaCan(Nodo *P, char *Nombre){
291

292 P->Palabra = Nombre;


293

294 if(*P->Palabra == *Nombre){


295

296 printf("\nSe capturo correctamente.\n");


297

298 }
299 else{
300

301 printf("\nNo se capturo correctamente.\n");


302 return -1;
303 }
304

305 printf("\n\nSe capturo: %s.\n", P->Palabra);


306

307 return 1;
308 }
309

310 int Init_ArrayLinked(){


311

312 int i, j, k;
313 int l = 0;
314 int m = 0;
315 int NUM;
316

317 //Asignamos memoria al arreglo


318 Array = (THash*)malloc(TAMAX*sizeof(THash));
319

320 if(Array == 0){


321

322 printf("\nNo se le asigno memoria correctamente al Arreglo.\n");


323 return -1;
324 }
325 else{
326

327 printf("\nSe creo correctamente el Arreglo.\n");


328 }
329

330

331 //Asignacion de memoria de cadda una de las listas


332 for( i = 0; i < TAMAX; i++ ){
333

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

339 if( (Array[i].Head = (Nodo*)malloc(sizeof(Nodo))) == 0){


340

341 printf("No hay espacio de memeria para crear la Lista


(H[%d])", i);
342 return -1;
343 }
344

345 if( (Array[i].Tail = (Nodo*)malloc(sizeof(Nodo))) == 0){


346

347 printf("No hay espacio de memeria para crear la Lista


(T[%d])", i);
348 free(Array[i].Head);
349 return -1;
350 }
351 }
352

353 for(j = 0; j < TAMAX; j++){


354

355 if( (Array[i].Head = (Nodo*)malloc(sizeof(Nodo))) == 0 &&


(Array[i].Tail = (Nodo*)malloc(sizeof(Nodo))) == 0 ){
356

357 printf("\nNo se creo correctamente la lista vacia del


arreglo[%d].", j);
358 return -1;
359 }
360 else{
361

362 printf("\nSe creo correctamente la lista vacia del


arreglo[%d].", j);
363

364 }
365 }
366

367 printf("\n\n");
368

369 //Conectamos Head y Tail de cada una de las listas


370 for(k = 0; k < TAMAX; k++){
371

372 Array[k].Head->Next = Array[k].Tail;


373 Array[k].Tail->Next = Array[k].Tail;
374

375 }
376

377 while(Array[l].Head->Next == Array[l].Tail){


378

89
379 printf("\nSe conecto correctamente Head y Tail.\n");
380 l++;
381

382 }
383

384 while(Array[m].Head->Next == Array[m].Tail){


385

386 printf("\nSe conecto correctamente Head y Tail.\n");


387 m++;
388

389 }
390

391 return 1;
392 }
393

394 int ArrayPosition(char *Palabra){


395

396 int i = 0;
397 int Suma = 0;
398 int Mod;
399

400 while( Palabra[i] != ’\n’ && Palabra[i] != ’\0’){


401

402 printf("texto[%d] == %c == %3d\n", i, Palabra[i], Palabra[i]);


403 Suma = Suma + Palabra[i];
404 i++;
405

406 }
407

408 printf("\nLa suma total es: %d\n", Suma);


409 Mod = Suma%30;
410 printf("\nEl modulo de %d es %d\n", Suma, Mod);
411

412

413 return Mod;


414 }
415

416 void AddFirst(THash *A, Nodo NewPalabra, int Mod){


417

418 //Inicializacion
419 THash *apH = A;
420 Nodo *apHMOD = apH[Mod].Head;
421 Nodo *Tail = apH[Mod].Tail;
422 Nodo *NewNodo = 0;
423

424 //Asignacion de memoria del Nodo nuevo a la lista


425 NewNodo = (Nodo*)malloc(sizeof(Nodo));
426

427 if( (NewNodo = (Nodo*)malloc(sizeof(Nodo))) == 0){


428

90
429 printf("\nNo se creo la memoria correctamente.\n");
430 }
431 else{
432

433 printf("\nSe creo correctamente la memoria.\n");


434 }
435

436 //Si la lista esta vacia


437 if(apHMOD->Next == Tail){
438

439 printf("\nLa lista en Array[%d] se encuentra vacia.\n", Mod);


440 *NewNodo = NewPalabra;
441 NewNodo->Next = Tail;
442 apHMOD->Next = NewNodo;
443

444 if(NewNodo->Next == Tail){


445

446 printf("\nEl nuevo nodo se conecto correctamente con


Tail.\n");
447 }
448 else{
449

450 printf("\nEl nuevo Nodo no se conecto correctamente con


Tail.\n");
451 }
452 }
453

454 //Si esta no esta vacia


455 else{
456

457 printf("\nLa lista en Array[%d] NO se encuentra vacia.\n", Mod);


458 *NewNodo = NewPalabra;
459 NewNodo->Next = Tail;
460 apHMOD->Next = NewNodo;
461 }
462

463

464 return;
465 }
466

467 void Display(){


468

469 int i;
470

471 for(i = 0; i < TAMAX; i++){


472

473 Nodo *temp = Array[i].Head;


474 Nodo *aux = Array[i].Tail;
475 Nodo *temp2 =temp->Next;
476

91
477 if(temp->Next == aux){
478

479 printf("\nArray[%d] no tiene elementos.\n", i);


480 }
481 else{
482

483 printf("\nArray[%d] tiene elementos.\n", i);


484 printf("| Array[%d] | ->\t %s ->\t", i, temp2->Palabra);
485 temp2 = temp2->Next;
486

487 }
488

489 printf("\n");
490 }
491

492

493 }
494

495 int ReadArchive(char *Path){


496

497 FILE *Archivo = 0;


498 char Caracter[30];
499 int Contador;
500

501 int Mod30;


502 int CapturaN;
503 Nodo P;
504

505

506 Archivo = fopen(Path, "r");


507

508 if(Archivo != 0){


509

510 //Mientras la linea de texto sea diferente del final (EOF)


511 while(!feof(Archivo)){
512

513

514 //Obtenemos los datos para poder agregar


515 fgets(Caracter, 50, Archivo);
516 printf("%s",Caracter);
517

518

519 CapturaCan(&P, Caracter);


520 Mod30 = ArrayPosition(Caracter);
521

522

523 }
524

525 AddFirst(Array, P, Mod30);


526 //rewind(Archivo);

92
527

528 fclose(Archivo);
529

530 }
531 else{
532

533 printf("\nError de apertura del archivo.\n\n");


534 return -1;
535 }
536

537 return 1;
538 }
539

540

541 /*FUNCIONES PARA EL ARBOL DE TRANSACCIONES*/


542

543 //Funcion para crear cada Nodo del Arbol de Transacciones


544 Nodo_AT *CreaNodoAT(char *url, char *candidato, char *word, int ascii){
545

546 Nodo_AT *Newitem = 0;


547 int SUM;
548

549 //Asignacion de memoria


550 Newitem = (Nodo_AT*)malloc(sizeof(Nodo_AT));
551

552 if( (Newitem = (Nodo_AT*)malloc(sizeof(Nodo_AT))) == 0){


553

554 printf("\nNo se creo la memoria correctamente.\n");


555 return Newitem;
556

557 }
558

559 //Agregando los datos a su campo debido del Nodo


560

561 Newitem->URL = url;


562 Newitem->Candidato = candidato;
563 Newitem->Word = word;
564 Newitem->ASCII = ascii;
565

566 //Aterrizamos los apuntadores


567 Newitem->Nleft = Newitem;
568 Newitem->Nrigh = Newitem;
569

570 return Newitem;


571 }
572

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

580 int Suma1 = 0;


581 int Suma2 = 0;
582 int Suma3 = 0;
583 int SUM;
584

585 while( url[i] != ’\n’ && url[i] != ’\0’){


586

587 //printf("texto[%d] == %c == %3d\n", i, url[i], url[i]);


588 Suma1 = Suma1 + url[i];
589 i++;
590

591 }
592

593

594 //printf("\nLa suma total del URL es: %d\n", Suma1);


595

596 while( c[j] != ’\n’ && c[j] != ’\0’){


597

598 //printf("texto[%d] == %c == %3d\n", j, c[j], c[j]);


599 Suma2 = Suma2 + c[j];
600 j++;
601

602 }
603

604

605 //printf("\nLa suma total del Candidato es: %d\n", Suma2);


606

607 while( w[k] != ’\n’ && w[k] != ’\0’){


608

609 //printf("texto[%d] == %c == %3d\n", i, w[k], w[k]);


610 Suma3 = Suma3 + w[k];
611 k++;
612

613 }
614

615 //printf("\nLa suma total del Candidato es: %d\n", Suma3);


616

617 SUM = Suma1 + Suma2 + Suma3;


618 printf("\nSuma total = %d\n", SUM);
619

620 return SUM;


621 }
622

623 void InserNAT(Nodo_AT *R, Nodo_AT *Item){


624

625 //Si el nuevo elemento es menor o igual a Raiz


626 if(Item->ASCII <= R->ASCII){

94
627

628 //Si raiz esta apuntandose a si mismo en Nleft(Izquierda)


629 if(R->Nleft == R){
630

631 R->Nleft = Item;


632 }
633

634 //Si esta ocupado


635 else{
636

637 //Raiz es ahora Nleft


638 InserNAT(R->Nleft, Item);
639 }
640 }
641

642 //Si el nuevo elemento es mayor que raiz


643 else{
644

645 //Si raiz esta apuntandose a si mismo en Nrigh(Derecha)


646 if(R->Nrigh == R){
647

648 R->Nrigh = Item;


649 }
650

651 //Si esta ocupado


652 else{
653

654 InserNAT(R->Nrigh, Item);


655 }
656 }
657

658 return;
659 }
660

661 /*Recorrido Preorden (NID)*/


662 void R_PRE(Nodo_AT *R){
663

664 //Imprime padre o Raiz


665 printf("\n%s\n", R->Candidato);
666

667 if(R->Nleft != R){


668

669 //Llamada recursiva para izq


670 R_PRE(R->Nleft);
671 }
672

673 if (R->Nrigh != R)
674 {
675 //Llamada recursiva para der
676 R_PRE(R->Nrigh);

95
677 }
678

679 return;
680 }
681

682 /*Recorrido Inorden (IND)*/


683 void R_INOR(Nodo_AT *R){
684

685 //Si la posicion izquierde esta ocupada, repide la recursividad en


esa posicion
686 if(R->Nleft != R){
687

688 R_INOR(R->Nleft);
689

690 }
691

692 //Imprime el padre del nodo


693 printf("\n%s\n", R->Candidato);
694

695 //Si la posicion derecha esta ocupada, repide recursividad en esa


posicion
696 if(R->Nrigh != R){
697

698 R_INOR(R->Nrigh);
699 }
700

701 return;
702 }
703

704 /*Recorrido Postorden (IDN)*/


705 void R_POSTOR(Nodo_AT *R){
706

707 // Si la posicion izquierda esta ocupada, repite de forma recursiva


en esa posicion.
708 if (R->Nleft != R){
709

710 R_POSTOR(R->Nleft);
711 }
712

713 // Si la posicion derecha esta ocupada, repite de forma recursiva en


esa posicion.
714 if (R->Nrigh != R){
715

716 R_POSTOR(R->Nrigh);
717 }
718

719 // Imprime el padre del nodo.


720 printf("\n%s\n", R->Candidato);
721

722 return;

96
723 }
724

725

726

727 /*FUNCIONES PARA EL ARBOL DUPLA*/


728 //Funcion para crear cada Nodo del Arbol de Transacciones
729 Nodo_DU *CreaNodoDu(char *candidato, char *word, int ascii){
730

731 Nodo_DU *Newitem = 0;


732 int SUM;
733

734 //Asignacion de memoria


735 Newitem = (Nodo_DU*)malloc(sizeof(Nodo_DU));
736

737 if( (Newitem = (Nodo_DU*)malloc(sizeof(Nodo_DU))) == 0){


738

739 printf("\nNo se creo la memoria correctamente.\n");


740 return Newitem;
741

742 }
743

744 //Agregando los datos a su campo debido del Nodo


745

746 Newitem->Candidato = candidato;


747 Newitem->Word = word;
748 Newitem->ASCII = ascii;
749

750 //Aterrizamos los apuntadores


751 Newitem->Nleft = Newitem;
752 Newitem->Nrigh = Newitem;
753

754 return Newitem;


755 }
756

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

763 int Suma2 = 0;


764 int Suma3 = 0;
765 int SUM;
766

767

768 //printf("\nLa suma total del URL es: %d\n", Suma1);


769

770 while( c[j] != ’\n’ && c[j] != ’\0’){


771

772 //printf("texto[%d] == %c == %3d\n", j, c[j], c[j]);

97
773 Suma2 = Suma2 + c[j];
774 j++;
775

776 }
777

778

779 //printf("\nLa suma total del Candidato es: %d\n", Suma2);


780

781 while( w[k] != ’\n’ && w[k] != ’\0’){


782

783 //printf("texto[%d] == %c == %3d\n", i, w[k], w[k]);


784 Suma3 = Suma3 + w[k];
785 k++;
786

787 }
788

789 //printf("\nLa suma total del Candidato es: %d\n", Suma3);


790

791 SUM = Suma2 + Suma3;


792 printf("\nSuma total = %d\n", SUM);
793

794 return SUM;


795 }
796

797 void InserNDU(Nodo_DU *R, Nodo_DU *Item){


798

799 //Si el nuevo elemento es menor o igual a Raiz


800 if(Item->ASCII <= R->ASCII){
801

802 //Si raiz esta apuntandose a si mismo en Nleft(Izquierda)


803 if(R->Nleft == R){
804

805 R->Nleft = Item;


806 }
807

808 //Si esta ocupado


809 else{
810

811 //Raiz es ahora Nleft


812 InserNDU(R->Nleft, Item);
813 }
814 }
815

816 //Si el nuevo elemento es mayor que raiz


817 else{
818

819 //Si raiz esta apuntandose a si mismo en Nrigh(Derecha)


820 if(R->Nrigh == R){
821

822 R->Nrigh = Item;

98
823 }
824

825 //Si esta ocupado


826 else{
827

828 InserNDU(R->Nrigh, Item);


829 }
830 }
831

832 return;
833 }
834

835 /*Recorrido Preorden (NID)*/


836 void PREDU_R(Nodo_DU *R){
837

838 //Imprime padre o Raiz


839 printf("\n%s\n", R->Candidato);
840

841 if(R->Nleft != R){


842

843 //Llamada recursiva para izq


844 PREDU_R(R->Nleft);
845 }
846

847 if (R->Nrigh != R)
848 {
849 //Llamada recursiva para der
850 PREDU_R(R->Nrigh);
851 }
852

853 return;
854 }
855

856 /*Recorrido Inorden (IND)*/


857 void INORDU_R(Nodo_DU *R){
858

859 //Si la posicion izquierde esta ocupada, repide la recursividad en


esa posicion
860 if(R->Nleft != R){
861

862 INORDU_R(R->Nleft);
863

864 }
865

866 //Imprime el padre del nodo


867 printf("\n%s\n", R->Candidato);
868

869 //Si la posicion derecha esta ocupada, repide recursividad en esa


posicion
870 if(R->Nrigh != R){

99
871

872 INORDU_R(R->Nrigh);
873 }
874

875 return;
876 }
877

878 /*Recorrido Postorden (IDN)*/


879 void POSTORDU_R(Nodo_DU *R){
880

881 // Si la posicion izquierda esta ocupada, repite de forma recursiva


en esa posicion.
882 if (R->Nleft != R){
883

884 POSTORDU_R(R->Nleft);
885 }
886

887 // Si la posicion derecha esta ocupada, repite de forma recursiva en


esa posicion.
888 if (R->Nrigh != R){
889

890 POSTORDU_R(R->Nrigh);
891 }
892

893 // Imprime el padre del nodo.


894 printf("\n%s\n", R->Candidato);
895

896 return;
897 }
898

899 //Funciones para la listas


900

901 //Funcion para Crear la lista


902 Candidato *CreaLSE(){
903

904 //Asignacion de memoria


905 Head_AMLO = ((Candidato*)malloc(sizeof(Candidato)));
906 Tail_AMLO = ((Candidato*)malloc(sizeof(Candidato)));
907

908 //Comprobacion de memoria


909 if( ( Head_AMLO = (Candidato*)malloc(sizeof(Candidato)) ) == 0){
910

911 //printf("No hay espacio de memeria para crear la Lista (H)");


912 return Head_AMLO;
913

914 }
915

916 if( (Tail_AMLO = (Candidato*)malloc(sizeof(Candidato)) ) == 0){


917

918 //printf("No hay espacio de memeria para crear la Lista (T)");

100
919 //Por si no hubo error en H
920 free(Head_AMLO);
921 return Tail_AMLO;
922

923 }
924

925 //Conectamos Head y Tail


926 Head_AMLO->Next = Tail_AMLO;
927 Tail_AMLO->Next = Tail_AMLO;
928

929 if(Head_AMLO->Next == Tail_AMLO){


930

931 //printf("\nSe concecto correctamente Head y Tail.\n");


932 }
933

934 return Head_AMLO;


935

936 }
937

938 Candidato *CreaLSE1(){


939

940 //Asignacion de memoria


941 Head_Anaya = ((Candidato*)malloc(sizeof(Candidato)));
942 Tail_Anaya = ((Candidato*)malloc(sizeof(Candidato)));
943

944 //Comprobacion de memoria


945 if( ( Head_Anaya = (Candidato*)malloc(sizeof(Candidato)) ) == 0){
946

947 //printf("No hay espacio de memeria para crear la Lista (H)");


948 return Head_Anaya;
949

950 }
951

952 if( (Tail_Anaya = (Candidato*)malloc(sizeof(Candidato)) ) == 0){


953

954 //printf("No hay espacio de memeria para crear la Lista (T)");


955 //Por si no hubo error en H
956 free(Head_Anaya);
957 return Tail_Anaya;
958

959 }
960

961 //Conectamos Head y Tail


962 Head_Anaya->Next = Tail_Anaya;
963 Tail_Anaya->Next = Tail_Anaya;
964

965 if(Head_Anaya->Next == Tail_Anaya){


966

967 //printf("\nSe concecto correctamente Head y Tail.\n");


968 }

101
969

970 return Head_Anaya;


971

972 }
973

974 Candidato *CreaLSE2(){


975

976 //Asignacion de memoria


977 Head_Meade = ((Candidato*)malloc(sizeof(Candidato)));
978 Tail_Meade = ((Candidato*)malloc(sizeof(Candidato)));
979

980 //Comprobacion de memoria


981 if( ( Head_Meade = (Candidato*)malloc(sizeof(Candidato)) ) == 0){
982

983 //printf("No hay espacio de memeria para crear la Lista (H)");


984 return Head_Meade;
985

986 }
987

988 if( (Tail_Meade = (Candidato*)malloc(sizeof(Candidato)) ) == 0){


989

990 //printf("No hay espacio de memeria para crear la Lista (T)");


991 //Por si no hubo error en H
992 free(Head_Meade);
993 return Tail_Meade;
994

995 }
996

997 //Conectamos Head y Tail


998 Head_Meade->Next = Tail_Meade;
999 Tail_Meade->Next = Tail_Meade;
1000

1001 if(Head_Meade->Next == Tail_Meade){


1002

1003 //printf("\nSe concecto correctamente Head y Tail.\n");


1004 }
1005

1006 return Head_Meade;


1007

1008 }
1009

1010 Candidato *CreaLSE3(){


1011

1012 //Asignacion de memoria


1013 Head_Zavala = ((Candidato*)malloc(sizeof(Candidato)));
1014 Tail_Zavala = ((Candidato*)malloc(sizeof(Candidato)));
1015

1016 //Comprobacion de memoria


1017 if( ( Head_Zavala = (Candidato*)malloc(sizeof(Candidato)) ) == 0){
1018

102
1019 //printf("No hay espacio de memeria para crear la Lista (H)");
1020 return Head_Zavala;
1021

1022 }
1023

1024 if( (Tail_Zavala = (Candidato*)malloc(sizeof(Candidato)) ) == 0){


1025

1026 //printf("No hay espacio de memeria para crear la Lista (T)");


1027 //Por si no hubo error en H
1028 free(Head_Zavala);
1029 return Tail_Zavala;
1030

1031 }
1032

1033 //Conectamos Head y Tail


1034 Head_Zavala->Next = Tail_Zavala;
1035 Tail_Zavala->Next = Tail_Zavala;
1036

1037 if(Head_Zavala->Next == Tail_Zavala){


1038

1039 //printf("\nSe concecto correctamente Head y Tail.\n");


1040 }
1041

1042 return Head_Zavala;


1043

1044 }
1045

1046 //Funcion para capturar el Nodo


1047 int CapturaCan(Candidato *P, char *Nombre){
1048

1049 P->Nombre = Nombre;


1050

1051 if(P->Nombre != 0){


1052

1053 //printf("\nSe capturo correctamente.");


1054

1055 }
1056

1057 //printf("\n\n%s", P->Nombre);


1058

1059 return 1;
1060 }
1061

1062 //Funcion para agregar al principio de la lista


1063 void AddFirst(Candidato *H, Candidato *T, Candidato Nodo){
1064

1065 //Inicializacion
1066 Candidato *apC = H;
1067 Candidato *NewNodo = 0;
1068

103
1069 //Asignacion de memoria
1070 NewNodo = (Candidato*)malloc(sizeof(Candidato));
1071

1072 if( (NewNodo = (Candidato*)malloc(sizeof(Candidato))) == 0){


1073

1074 //printf("\nNo se creo la memoria correctamente.\n");


1075 }
1076 else{
1077

1078 //printf("\nSe creo correctamente la memoria.\n");


1079 }
1080

1081 //Si no esta vacia


1082 if(apC->Next != T){
1083

1084 //printf("\nNo esta vacia.");


1085 *NewNodo = Nodo;
1086 NewNodo->Next = H->Next;
1087 apC->Next = NewNodo;
1088 }
1089

1090 //Si esta vacia


1091 else{
1092

1093 *NewNodo = Nodo;


1094 NewNodo->Next = T;
1095 apC->Next = NewNodo;
1096 //printf("\nEsta vacia.");
1097

1098 }
1099

1100 if(NewNodo->Next == T){


1101

1102 //printf("\nYEAP.");
1103 }
1104 else{
1105

1106 //printf("\nNOOO");
1107 }
1108

1109 //printf("\nOK");
1110

1111 return;
1112 }
1113

1114 //Funcion para Eliminar por atras


1115 int EliminarXATLSE(Candidato *H, Candidato *T){
1116

1117 Candidato *apC = H;


1118 Candidato *aux1 = H->Next;

104
1119

1120 //Si esta vacia


1121 if(aux1->Next == T){
1122

1123 printf("\nNo se puede eliminar elemento porque la lista esta


vacia\n");
1124

1125 return -1;


1126

1127 }
1128

1129 while(apC->Next->Next != T){


1130

1131 aux1 = aux1->Next;


1132 apC = apC->Next;
1133

1134 }
1135

1136 apC->Next = T;
1137 free(aux1);
1138

1139 return 1;
1140 }
1141

1142 //Funcion para imprimir los elementos de la lista


1143 void ListarLSE(Candidato *H, Candidato *T){
1144

1145 Candidato *apC = H;


1146 Candidato *aux = T;
1147

1148 printf("\n\n");
1149

1150

1151 while(apC->Next != T){


1152

1153 printf("%s -> ", apC->Next->Nombre);


1154 apC = apC->Next;
1155 }
1156

1157 return;
1158 }
1159

1160 int CreaAMLO(){


1161

1162 //Variables de los Nombres de la lista


1163 char Nombre[30] = "AMLO";
1164 char Nombre1[30] = "Andres Manuel Lopez Obrador";
1165 char Nombre2[30] = "Lopez Obrador";
1166 char Nombre3[30] = "Morena";
1167 char Nombre4[30] = "Juntos Haremos Historia";

105
1168

1169 //Variables para crear la lista completa


1170 Candidato item, item1, item2, item3, item4;
1171 int X, X1, X2, X3, X4;
1172

1173

1174 //Funcion que inicializa la lista


1175 Head_AMLO = CreaLSE();
1176

1177 //Capturacion de los Nombres


1178 X = CapturaCan(&item, Nombre);
1179 X1 = CapturaCan(&item1, Nombre1);
1180 X2 = CapturaCan(&item2, Nombre2);
1181 X3 = CapturaCan(&item3, Nombre3);
1182 X4 = CapturaCan(&item4, Nombre4);
1183

1184 if(X == 1 && X3 == 1){


1185

1186 //printf("\nSe capturo correctamente el Nodo.\n");


1187 }
1188 else{
1189

1190 //printf("\nNo se capturo correctamente.\n");


1191 return -1;
1192 }
1193

1194 //Agregando los Nodos a la Lista


1195 AddFirst(Head_AMLO, Tail_AMLO, item);
1196 AddFirst(Head_AMLO, Tail_AMLO, item1);
1197 AddFirst(Head_AMLO, Tail_AMLO, item2);
1198 AddFirst(Head_AMLO, Tail_AMLO, item3);
1199 AddFirst(Head_AMLO, Tail_AMLO, item4);
1200

1201 //Impresion de la lista


1202 ListarLSE(Head_AMLO, Tail_AMLO);
1203

1204 return 1;
1205 }
1206

1207 int CreaAnaya(){


1208

1209 //Variables de los Nombres de la lista


1210 char Nombre[30] = "Anaya";
1211 char Nombre1[30] = "Ricardo Anaya Cortes";
1212 char Nombre2[30] = "Ricardo Anaya";
1213 char Nombre3[30] = "Mexico al Frente";
1214 char Nombre4[30] = "PAN";
1215

1216

1217 //Variables para crear la lista completa

106
1218 Candidato item, item1, item2, item3, item4;
1219 int X, X1, X2, X3, X4;
1220

1221 Head_Anaya = CreaLSE1();


1222

1223 //Capturacion de los Nombres


1224 X = CapturaCan(&item, Nombre);
1225 X1 = CapturaCan(&item1, Nombre1);
1226 X2 = CapturaCan(&item2, Nombre2);
1227 X3 = CapturaCan(&item3, Nombre3);
1228 X4 = CapturaCan(&item4, Nombre4);
1229

1230 if(X == 1 && X3 == 1){


1231

1232 //printf("\nSe capturo correctamente el Nodo.\n");


1233 }
1234 else{
1235

1236 //printf("\nNo se capturo correctamente.\n");


1237 return -1;
1238 }
1239

1240 //Agregando los Nodos a la Lista


1241 AddFirst(Head_Anaya, Tail_Anaya, item);
1242 AddFirst(Head_Anaya, Tail_Anaya, item1);
1243 AddFirst(Head_Anaya, Tail_Anaya, item2);
1244 AddFirst(Head_Anaya, Tail_Anaya, item3);
1245 AddFirst(Head_Anaya, Tail_Anaya, item4);
1246

1247 //Impresion de la lista


1248 ListarLSE(Head_Anaya, Tail_Anaya);
1249

1250 return 1;
1251 }
1252

1253 int CreaMeade(){


1254

1255 //Variables de los Nombres de la lista


1256 char Nombre[30] = "Jose Antonio Meade Kuribrena";
1257 char Nombre1[30] = "Meade";
1258 char Nombre2[30] = "Jose Antonio Meade";
1259 char Nombre3[30] = "Todos por Mexico";
1260 char Nombre4[30] = "PRI";
1261

1262

1263 //Variables para crear la lista completa


1264 Candidato item, item1, item2, item3, item4;
1265 int X, X1, X2, X3, X4;
1266

1267 Head_Meade = CreaLSE2();

107
1268

1269 //Capturacion de los Nombres


1270 X = CapturaCan(&item, Nombre);
1271 X1 = CapturaCan(&item1, Nombre1);
1272 X2 = CapturaCan(&item2, Nombre2);
1273 X3 = CapturaCan(&item3, Nombre3);
1274 X4 = CapturaCan(&item4, Nombre4);
1275

1276 if(X == 1 && X3 == 1){


1277

1278 //printf("\nSe capturo correctamente el Nodo.\n");


1279 }
1280 else{
1281

1282 //printf("\nNo se capturo correctamente.\n");


1283 return -1;
1284 }
1285

1286 //Agregando los Nodos a la Lista


1287 AddFirst(Head_Meade, Tail_Meade, item);
1288 AddFirst(Head_Meade, Tail_Meade, item1);
1289 AddFirst(Head_Meade, Tail_Meade, item2);
1290 AddFirst(Head_Meade, Tail_Meade, item3);
1291 AddFirst(Head_Meade, Tail_Meade, item4);
1292

1293 //Impresion de la lista


1294 ListarLSE(Head_Meade, Tail_Meade);
1295

1296 return 1;
1297 }
1298

1299 int CreaZavala(){


1300

1301 //Variables de los Nombres de la lista


1302 char Nombre[30] = "Margarita Ester Zavala Gomez";
1303 char Nombre1[30] = "Margarita Zavala";
1304 char Nombre2[30] = "Zavala";
1305

1306 //Variables para crear la lista completa


1307 Candidato item, item1, item2;
1308 int X, X1, X2;
1309

1310 Head_Zavala = CreaLSE3();


1311

1312 //Capturacion de los Nombres


1313 X = CapturaCan(&item, Nombre);
1314 X1 = CapturaCan(&item1, Nombre1);
1315 X2 = CapturaCan(&item2, Nombre2);
1316

1317 if(X == 1 && X1 == 1){

108
1318

1319 //printf("\nSe capturo correctamente el Nodo.\n");


1320 }
1321 else{
1322

1323 //printf("\nNo se capturo correctamente.\n");


1324 return -1;
1325 }
1326

1327 //Agregando los Nodos a la Lista


1328 AddFirst(Head_Zavala, Tail_Zavala, item);
1329 AddFirst(Head_Zavala, Tail_Zavala, item1);
1330 AddFirst(Head_Zavala, Tail_Zavala, item2);
1331

1332 //Impresion de la lista


1333 ListarLSE(Head_Zavala, Tail_Zavala);
1334

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).

Figure 21: Representación de un Grafo

Un grafo G es un conjunto en el que hay definida una relación binaria,es decir,


G=(V,A) tal que V es un conjunto de objetos a los que denominaremos vértices
o nodos y A Í V x V es una relación binaria a cuyos elementos denominaremos
arcos o aristas.

Figure 22: Representación de un Nodo del Grafo

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

Listing 6: Programa en C DFS y BFS.


1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <memory.h>
5

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

15 typedef struct nodo //Estructura del nodo


16 {
17 int * vertice; //Vertice de tipo int
18 struct nodo* next; // Apuntador que nos enlaza al nodo siguinte
19 }nodo;
20

21 typedef struct grafo //Estructura de grafo


22 {
23 int numver; //Numero de vertices del grafo.
24 struct nodo** listadj; //Matriz de tipo nodo para la lista de
ayacencia.
25 int* color; //Color que nos va a indicar si ya se recorrio el
nodo.
26 };
27

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

51 printf("Teclea el numero de relaciones: ");


52 scanf("%i", &vert);
53

54

55 struct grafo* graph = CreaGrafo(vert);


56 printf("Ingresa los nodos relacionados\n");
57 for(i=0; i < vert; i++)
58 {
59 int dad;
60 int son;
61 scanf("\n%i",&dad);
62 printf("\n Nodo padre es: %d ", dad);
63 scanf("\n%i",&son);
64 printf("\n Nodo Hijo es: %d ", son);
65 //Llamo a funcion para crear relacion
66 addRelacion(graph, dad, son);
67 }
68

69 printf("Que tipo de busqueda quiere hacer");


70 printf("\n Seleccione: 1) Para BFS (Breadth First Search) o 2) Para
Deep First Search" );
71 scanf("%u", &menu);
72

73 if(menu == 1)
74 {
75

76 BFS(graph, 0);
77 imprimirgrafo(graph);
78 }
79 else if(menu == 2)
80 {
81

82 printf("Ingresa el nudo por el cual iniciara la busqueda DFS:");


83 scanf("%i",&start);
84

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

98 //Nombre de la funcion: CreaGarfo.


99 //Descripcion: Crea y da memoria al nuevo grafo, a sus campos listadj y
color.
100 //Entradas: int vertices (el numero de vertices para el grafo)
101 //Salidas: El nuevo grafo.
102 struct grafo* CreaGrafo(int vertices)
103 {
104 struct grafo* graph = malloc(sizeof(struct grafo));
105 graph->numver=vertices;
106 graph->listadj=malloc(vertices * sizeof(struct nodo*));
107 graph->color=malloc(vertices * sizeof(int));
108 int i;
109 for(i=0;i<vertices;i++)
110 {
111 graph->listadj[i]=NULL;
112 graph->color[i]=0;
113 }
114 return graph; //Regresamos el grafo
115 }
116

117 //Nombre de la funcion: CreaNodo


118 //Descripcion: Crea y da memoria al nuevo nodo y damos valor a sus
campos.
119 //Entradas: int n que sera el valor que le daremos al campo "vertice"
120 //Salidas: Nos regresa elnuevo nodo
121 struct nodo * CreaNodo(int n) //Funcion para crear nodo
122 {
123 struct nodo* newnodo=malloc(sizeof(struct nodo));
124 newnodo->vertice=n; //Iguala el campo vertice del nuevo nodo al
valor n ingresado
125 newnodo->next=NULL; //Iguala el campo next del nuevo nodo a nulo
126 return newnodo; //Regresa el nuevo nodo
127 }
128

129

130 //Nombre de la funcion: CreaCola.


131 //Descripcion: Crea y da memoria a la nueva cola y se posisiona en -1 su
campo adelante y atras.

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

142 //Nombre de la funcion: isempty


143 //Descripcion: Verifica que la cola este vacia.
144 //Entradas: La cola (q)
145 //Salidas: Bandera para saber si esta o no esta vacia.
146 int isempty(struct queue* q)
147 {
148 if(q->atras==-1)
149 {
150 return 1;
151 }
152 else
153 {
154 return 0;
155 }
156 }
157

158 //Nombre de la funcion: Encolar.


159 //Descripcion: Agrega a la cola el elemnto que se le pase como argumento.
160 //Entradas: La cola y el elelmento a encolar.
161 //Salidas: Nada.
162 void Encolar(struct queue* q, int v)
163 {
164 if(q->atras==(10-1))
165 {
166 printf("Cola llena");
167 }
168 else
169 {
170 if(q->atras==-1)
171 {
172 q->adelante=0;
173 }
174 q->atras++;
175 q->QueueVer[q->atras]=v;
176 }
177 }
178

179

180 //Nombre de la funcion: DesEncolar.


181 //Descripcion: Se quita un elemento de la cola.

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

205 //Nombre de la funcion: imprimircola


206 //Descripcion: Imprime todos los elementos de la cola, primero
verificando si esta vacia.
207 //Entradas: La cola.
208 //Salidas: Nada.
209 void imprimircola(struct queue *q)
210 {
211 int i=q->adelante;
212 if(isempty(q))
213 {
214 printf("La cola esta vacia");
215 }
216 else
217 {
218 printf("\nLa cola contiene\n");
219 for(i=q->adelante;i<q->atras+1;i++)
220 {
221 printf("%d",q->QueueVer[i]);
222 }
223 }
224 }
225

226 //Nombre de la funcion: imprimirgrafo.


227 //Descripcion: Imprime el contenido del grafo.
228 //Entradas: El grafo.
229 //Salidas: Nada.
230

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

248 //Nombre de la funcion: BFS.


249 //Descripcion: Funcion de busqueda y recorrido breadth first search.
250 //Entradas: El grafo y el vertice donde se inicia la busqueda.
251 //Salidas: Nada.
252 void BFS(struct grafo* graph, int iniciavertices)
253 {
254 struct queue* q=CreaCola();
255 graph->color[iniciavertices]=1;
256 Encolar(q, iniciavertices);
257 while(!isempty(q))
258 {
259 imprimircola(q);
260 int vertact=DesEncolar(q);
261 struct nodo* temp=graph->listadj[vertact];
262 while(temp)
263 {
264 int vertadj=temp->vertice;
265 if(graph->color[vertadj]==0)
266 {
267 graph->color[vertadj]=1;
268 Encolar(q, vertadj);
269 }
270 temp=temp->next;
271 }
272 }
273 printf("\nLa busqueda BFS a terminado\n");
274 }
275

276

277 //Nombre de la funcion: DFS.


278 //Descripcion: Funcion de busqueda y recorrido deep first search
279 //Entradas: El grafo y el valor donde inicia la busqueda.
280 //Salidas: Nada.

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

300 //Nombre de la funcion: DFS.


301 //Descripcion: Funcion para anadir relacion de los elementos ingresados.
302 //Entradas: El grafo y los valores desde y hacia para crear los
respectivos nodos, crear relacion y ubicarlos.
303 //Salidas: Nada.
304 void addRelacion(struct grafo* graph, int desde, int hacia)
305 {
306 struct nodo* newnodo=CreaNodo(hacia);
307 newnodo->next=graph->listadj[desde];
308 graph->listadj[desde]=newnodo;
309 newnodo=CreaNodo(desde);
310 newnodo->next=graph->listadj[hacia];
311 graph->listadj[hacia]=newnodo;
312 }

117
3.1.3 Entradas

3.1.4 Salidas

3.1.5 Link del Programa


Para consulta puede ingresar al siguiente link para verificar el programa: https:
//code.hackerearth.com/e26299h

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.

Un árbol es un grafo conexo a cı́clico, y para cada par de vértices distintos


sólo existirá un único camino. Un árbol está conformado por vértices (nodos)
y arcos (aristas), al igual que un grafo. Si existe un camino de longitud 1 entre
dos nodos en un árbol uno de ellos será el padre y el otro será el hijo. Los
vértices pueden ser de tres tipos:

Raı́z: Es el único nodo que no tiene padre.


Nodo Interno: Es aquel que posee al menos un hijo.
Nodo Externo: Es aquel que no tiene hijos, también se le denomina hoja.

Figure 23: BFS

Figure 24: DFS

Figure 25: Representación de BFS y DFS

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.

Realice las estructuras de datos y funciones necesarias.

3.2.2 Código en C

Listing 7: Programa en C DFS y BFS.


1 #include <stdio.h>
2 #include <math.h>
3

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

14 /*Arreglos Globales para los Recorridos*/


15 int Color[SIZE];
16 int Fathersuki[SIZE];
17 int Distancia[SIZE];
18

19 /*Estructura de la Lista de Adj*/


20 typedef struct {
21

22 char *Vertice;
23 unsigned Num;
24 struct Nodo_Ver *Head;
25 struct Nodo_Ver *Tail;
26

27 }MLista;
28

29

30 /*Estructura del Nodo para el DFS*/


31 typedef struct Nodo_Ver{
32

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

47 /*Estructura para la cola*/


48 typedef struct Queuei{
49

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

67 /*Nombre de la funcion: Captura_V


68 Descripcion de la funcion: Esta funcion se usa para capturar el numero
de vertice y asi inicializar el grafo.
69 Entradas: No recibe parametros.
70 Salidas: Como la funcion es tipo void no regresa nada.*/
71 void Captura_V();
72

73 /*Nombre de la funcion: Captura_TV


74 Descripcion de la funcion: Esta funcion se usa para capturar la letra de
los vertices e ir agregandolas al grafo.
75 Entradas: No recibe parametros.
76 Salidas: Como la funcion es tipo void no regresa nada.*/
77 void Captura_TV();
78

79 /*Nombre de la funcion: Captura_Cx


80 Descripcion de la funcion: Esta funcion se usa para capturar el numero
de vertice y asi inicializar el grafo.
81 Entradas: No recibe parametros.
82 Salidas: Como la funcion es tipo void no regresa nada.*/
83 void Captura_Cx();
84

85 /*Nombre de la funcion: Init_ArrayLinked

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

91 /*Nombre de la funcion: CapturaN


92 Descripcion de la funcion: Esta funcion se usa para capturar la
informacion de un Nodo.
93 Entradas: Recibe una variable tipo MLista* que es el nuevo elemento y
recibe una variable tipo char que es el nombre del vertice para
crear el Nodo.
94 Salidas: Como la funcion es tipo void no regresa nada, solo captura.*/
95 void CapturaN(MLista *V, char *NV);
96

97 /*Nombre de la funcion: PosVer


98 Descripcion de la funcion: Esta funcion se usa para recorer la lista de
adyacnecia y devolver la posicion de un vertice.
99 Entradas: Recibe el nombre del vertice a buscar.
100 Salidas: Como la funcion es tipo unsigned solo regresa la posicion del
vertice.*/
101 unsigned PosVer(char *Vertice);
102

103 /*Nombre de la funcion: Captura_S


104 Descripcion de la funcion: Esta funcion se usa para capturar el tipo de
busqueda que quiera realizar el usuario.
105 Entradas: No recibe parametros.
106 Salidas: Como la funcion es tipo unsigned, regresa la busqueda
seleccionada.*/
107 unsigned Captura_S();
108

109 /*Nombre de la funcion: AddT


110 Descripcion de la funcion: Esta funcion se usa para capturar el el
vertice y colocarlo en el Array con sus respectivos datos.
111 Entradas: Recibe la lista de adyacencia.
112 Salidas: Como la funcion es tipo void no regresa nada, solo agrega en el
Array.*/
113 void AddT(MLista *A, char *NV, unsigned Pos);
114

115 //Funciones de la cola


116

117 /*Nombre de la funcion: Captura_V


118 Descripcion de la funcion: Esta funcion se usa para capturar el numero
de vertice y asi inicializar el grafo.
119 Entradas: No recibe parametros.
120 Salidas: Como la funcion es tipo void no regresa nada.*/
121 Queuei *CreaQ(unsigned Limit);
122

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

129 /*Nombre de la funcion: DeQueueQ


130 Descripcion de la funcion: Esta funcion se usa para eliminar un elemento
de la cola.
131 Entradas: Recibe como parametro la cola.
132 Salidas: Como la funcion es tipo Nodo_Q regresa el vertice eliminado
para hacer BFS.*/
133 Nodo_Q *DeQueueQ(Queuei *Q);
134

135 /*Nombre de la funcion: isEmpty


136 Descripcion de la funcion: Esta funcion se usa para verificar si la cola
esta vacia.
137 Entradas: Recibe la cola como parametro.
138 Salidas: Como la funcion es tipo int regresa 1 si esta vacia.*/
139 int isEmpty(Queuei *Q);
140

141

142 //BFS
143

144 /*Nombre de la funcion: SelecV


145 Descripcion de la funcion: Esta funcion se usa para capturar el vertice
con el que va a comenzar BFS.
146 Entradas: Recibe la lista de adyacencia.
147 Salidas: Como la funcion es tipo unsigned, regresa la posicion del
vertice.*/
148 unsigned SelecV(MLista *A);
149

150 /*Nombre de la funcion: RecorreML


151 Descripcion de la funcion: Esta funcion se usa para recorrer la lista de
adyacencia en busca de vertices.
152 Entradas: Recibo como parametro a ls lista de adyacencia y al vertice a
buscar.
153 Salidas: Como la funcion es tipo Nodo_Ver regresa el vertice encontrado*/
154 Nodo_Ver *RecorreML(MLista *A, char *V);
155

156

157 //Funciones de los Arreglos de datos


158

159 /*Nombre de la funcion: ImpriemAD, ImprimeArrayC, ImprimeArrayF


160 Descripcion de la funcion: Esta funcion se usa para imprimir el
contenido de cada uno de los arreglos.
161 Entradas: No recibe parametros.

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

168 int main()


169 {
170 //Inicializacion
171 int Init;
172 unsigned Selec;
173 unsigned S;
174

175 //Esta funcion pide le numero de vertices


176 Captura_V();
177

178 //Inicializamos la matriz (Array con el numero de Verices)


179 Init = Init_ArrayLinked(NumV);
180

181 //Capturamos los vertices en el Array


182 Captura_TV();
183

184 //Capturamos las conexiones de cada vertice y creamos su lista de Adj


185 Captura_Cx();
186

187 printf("\n MATRIZ DE AYACENCIA \n");


188 Display();
189

190 Selec = Captura_S();


191

192 if(Selec == 1){


193

194

195 S = SelecV(Array);
196

197 //Si es diferente de vacio


198 if(S != ’0’){
199

200 BFS(Array, S);


201

202

203 //printf("\n\n");
204 //ImprimeArrayC(Color);
205 //ImprimeArrayF(Fathersuki);
206 //ImprimeArrayD(Distancia);
207 }
208

209 }
210

211 if(Selec == 2){

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

229 //Funciones para crear la Tabla


230 void Captura_V(){
231

232 //Pedimos la cantidad de vertices


233 //printf("\nCuantos vertices quieres en el Grafo\n");
234 scanf("%u", &NumV);
235 //printf("%u", NumV);
236 //printf("\n\n");
237

238 return;
239 }
240

241 void Captura_TV(){


242

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

252 scanf(" %[^\t\n]s",&Vertices);


253 //printf("\n\nLos Vertices son: %s\n", Vertices);
254

255 P = Vertices;
256 //printf("\n%s", P);
257

258 for(j = 0; j < (NumV*2)-1; j++){


259

260 if(P[j] != ’ ’){


261

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

274 void Captura_Cx(){


275 //Inicializacion
276 char Vertices[30];
277 int i , j;
278 char *P = 0;
279 char *Ver = 0;
280 char *P1 = 0;
281

282 unsigned Posicion;


283

284 for(i = 0; i < NumV; i++){


285

286 scanf(" %[^\t\n]s",&Vertices);


287 //printf("\n\nLos Vertices son: %s\n", Vertices);
288

289 P = Vertices;
290 //printf("\n%s", P);
291

292

293 for(j = 1; j < NumV*2; j++){


294

295 if(P[j] != ’ ’ && P[j] != 0){


296

297 Ver = P[j];


298

299 //Buscamos la posicion de la letra


300 Posicion = PosVer(Ver);
301 //printf("\nLetra: %c", Ver);
302 //printf("\nPos: %d\n", Posicion);
303

304 //Inicializacion
305 Nodo_Ver *apH = Array[i].Head;
306 Nodo_Ver *aux = Array[i].Head->Next;
307 Nodo_Ver *N = 0;
308

309 //Asignacion de memoria


310 N = (Nodo_Ver*)malloc(sizeof(Nodo_Ver));
311

126
312 if( (N = (Nodo_Ver*)malloc(sizeof(Nodo_Ver))) == 0){
313

314 //printf("\nNo se pudo crear la memoria");


315 }
316 else{
317

318 //printf("\nSe pudo crear la memoria\n");


319 }
320

321

322 while(apH->Next->Next != aux){


323

324 aux = aux->Next;


325 apH = apH->Next;
326 //printf("\nRecorriendo..");
327 }
328

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

341 void CapturaN(MLista *V, char *NV){


342

343 V->Vertice = NV;


344 //printf("\nEs: %c", V->Vertice);
345

346 return;
347 }
348

349 void AddT(MLista *A, char *NV, unsigned Pos){


350

351 //Inicializacion
352 MLista *apH = A;
353

354 A[Pos].Vertice = NV;


355 A[Pos].Num = Pos;
356

357 return;
358 }
359

360 //Funcion que incializa la Matriz de Adj vacia


361 int Init_ArrayLinked(unsigned Size){

127
362

363 int i, j, k, l;
364 int m = 0;
365

366 //Asignacion de memoria del Arreglo


367 Array = (MLista*)malloc(Size*sizeof(MLista));
368

369 if(Array == 0){


370

371 //printf("\nNo se le asigno memoria correctamente al


Arreglo.\n");
372 return -1;
373 }
374 else{
375

376 //printf("\nSe creo correctamente el Arreglo.\n");


377 }
378

379

380

381 //Asignacion de memoria de cada una de las listas


382 for( i = 0; i < Size; i++ ){
383

384 Array[i].Head = (Nodo_Ver*)malloc(sizeof(Nodo_Ver));


385 Array[i].Tail = (Nodo_Ver*)malloc(sizeof(Nodo_Ver));
386

387

388 if( (Array[i].Head = (Nodo_Ver*)malloc(sizeof(Nodo_Ver))) == 0){


389

390 //printf("No hay espacio de memeria para crear la Lista


(H[%d])", i);
391 return -1;
392 }
393

394 if( (Array[i].Tail = (Nodo_Ver*)malloc(sizeof(Nodo_Ver))) == 0){


395

396 //printf("No hay espacio de memeria para crear la Lista


(T[%d])", i);
397 free(Array[i].Head);
398 return -1;
399 }
400 }
401

402 //Comprobacion de memoria


403 for(j = 0; j < Size; j++){
404

405 if( (Array[i].Head = (Nodo_Ver*)malloc(sizeof(Nodo_Ver))) == 0


&& (Array[i].Tail = (Nodo_Ver*)malloc(sizeof(Nodo_Ver))) ==
0 ){
406

128
407 //printf("\nNo se creo correctamente la lista vacia del
arreglo[%d].", j);
408 return -1;
409 }
410 else{
411

412 //printf("\nSe creo correctamente la lista vacia del


arreglo[%d].", j);
413

414 }
415 }
416

417

418 //printf("\n\n");
419

420 //Conectamos Head y Tail de cada una de las listas


421 for(k = 0; k < Size; k++){
422

423 Array[k].Head->Next = Array[k].Tail;


424 Array[k].Tail->Next = Array[k].Tail;
425

426 }
427

428 for(l = 0; l < Size; l ++){


429

430 if( (Array[l].Head->Next == Array[l].Tail) ){


431

432 //printf("\nSe conecto correctamente Head y Tail.");


433 }
434 else{
435

436 //printf("\nNo conecto correctamente Head y Tail.");


437 return -1;
438 }
439 }
440

441 printf("\n\n");
442

443 for(m = 0; m < Size; m ++){


444

445 if( (Array[m].Tail->Next == Array[m].Tail) ){


446

447 //printf("\nSe conecto correctamente Tail consigo mismo.");


448 }
449 else{
450

451 //printf("\nNo conecto correctamente Tail consigo mismo.");


452 return -1;
453 }
454 }

129
455

456 return 1;
457

458 }
459

460 //Recorre el arreglo de la Adj para devolver la posicion de un vertice


461 unsigned PosVer(char *Vertice){
462

463 unsigned i;
464

465 for(i = 0; i < NumV; i++){


466

467 if(Array[i].Vertice == Vertice){


468

469 //printf("\nLa letra es: %c su posicion es: %u\n",


Array[i].Vertice, i);
470 return i;
471 }
472 }
473 }
474

475 //Funcion que imprime la lista de Adj


476 void Display(){
477

478 int i;
479 MLista *apL = Array;
480

481 printf("\n\n");
482

483 for(i = 0; i < NumV; i++){


484

485

486

487 if( apL[i].Vertice == 0){


488

489 printf("\n| El Array[%d] no tiene Vertice |\n", i);


490

491 }
492 else{
493

494 //Inicializacion
495 Nodo_Ver *apH = apL[i].Head;
496 Nodo_Ver *aux = apL[i].Tail;
497

498 printf("| Vertice en el Array[%d] es: %c |", i,


apL[i].Vertice);
499

500 while(apH->Next != aux){


501

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

516 //Funcion seleccion Busqueda


517 unsigned Captura_S(){
518

519 unsigned Search;


520

521 //Que tipo de algoritmo de busqueda BFS y DFS realizara


522 printf("\n\nSeleccione el tipo de busqueda 1.BFS 2.DFS\n");
523 scanf("%u", &Search);
524

525 if(Search == 1){


526

527 printf("Usted selecciono BFS\n");


528 }
529

530 if(Search == 2){


531

532 printf("Usted selecciono DFS\n");


533 }
534

535

536 if(Search != 1 && Search != 2){


537

538 printf("\nNo Selecciono una Opcion Valida.\n");


539 }
540

541 return Search;


542 }
543

544 //Funcion de seleccionar vertice unsigned para BFS


545 unsigned SelecV(MLista *A){
546

547 //Inicializacion
548 char *NV = 0;
549 int i;
550

131
551 printf("\nCon que vertice quiere empezar");
552 scanf("%s", &NV);
553

554 printf("\nVertice que escogio: %c\n", NV);


555

556

557 for(i = 0; i < NumV; i++){


558

559 //printf("\nArray %d es %c", i, Array[i].Vertice);


560

561 if(Array[i].Vertice == NV){


562

563 //printf("\nSe ha encontrado coincidencia...\n");


564 //printf("Posicion: %u", Array[i].Num);
565 return Array[i].Num;
566

567 }
568 else{
569

570 //printf("\nNo se encontro coincidencia...\n");


571 }
572 }
573

574 }
575

576 //Funcion para volver Nodo_Q mi Vertice de comienzo


577 Nodo_Q *CapturaN_VQ(unsigned Po, char *NV){
578

579 //Inicializacion
580 Nodo_Q *item = 0;
581

582 //Asignacion de memoria


583 item = (Nodo_Q*)malloc(sizeof(Nodo_Q));
584 item->Data = (Nodo_Ver*)malloc(sizeof(Nodo_Ver));
585

586 if( (item = (Nodo_Q*)malloc(sizeof(Nodo_Q))) == 0){


587

588 printf("\nNo hay memoria para crear un item de Queue");


589 return item;
590 }
591

592 if( (item->Data = (Nodo_Ver*)malloc(sizeof(Nodo_Ver))) == 0){


593

594 printf("\nNo hay memoria para crear un item de Queue en


Nodo_Ver");
595 return item;
596

597 }
598

599 //Copiamos la infromacion

132
600 item->Data->Vertice = NV;
601 item->Data->Numseq = Po;
602

603 return item;


604 }
605

606 //Funcion de seleccionar vertice Nodo_Ver unsigned para BFS


607 Nodo_Q* SelecVML(MLista *A, unsigned Pos){
608

609 //Inicializacion
610 char *NV = 0;
611 Nodo_Q *Newitem;
612 int i;
613

614

615 for(i = 0; i < NumV; i++){


616

617 if(Array[i].Num == Pos){


618

619 //printf("\nSe ha encontrado coincidencia...");


620 //printf("\nLetra %c\n", Array[i].Vertice);
621 NV = Array[i].Vertice;
622 //printf("\nLetra %c\n", NV);
623 Newitem = CapturaN_VQ(Pos, NV);
624 return Newitem;
625 }
626 else{
627

628 //printf("\nNo se encontro coincidencia...\n");


629 }
630 }
631

632 }
633

634 //Funciones para la Cola


635 Queuei *CreaQ(unsigned Limit){
636

637 //Asignacion de memoria


638 Queue = (Queuei*)malloc(sizeof(Queuei));
639

640 //Verificacion de memoria


641 if( (Queue = (Queuei*)malloc(sizeof(Queuei))) == 0){
642

643 printf("\nNo hay espacio de memoria para crear la Queue.");


644 return Queue;
645 }
646 else{
647

648 printf("\nLa memoria de la Queue se creo perfectamente.");


649 }

133
650

651 if(Limit <= 0){


652

653 Limit = 50;


654 }
655

656 //Asignacion de informacion


657 Queue->Limit = Limit;
658 Queue->Size = 0;
659 Queue->Head = NULL;
660 Queue->Tail = NULL;
661

662 return Queue;


663 }
664

665 //Funcion para insertar Vertice a la cola


666 int Enqueue(Queuei *Q, Nodo_Q *item){
667

668 //Pruebas de errores


669 if( (Q == 0) || (item == 0)){
670

671 printf("\nNo se pasaron bien los parametros, error.");


672 return FALSE;
673 }
674 else{
675

676 printf("\nAgregando a Cola...");


677 }
678

679 //Error de espacio de memoria


680 if(Q->Size >= Q->Limit){
681

682 printf("\nLa memoria y el espacio no fueron creadas


equivalentemente o no es menor Size");
683 return FALSE;
684 }
685

686 //En caso de estar vacia


687 item->prev = NULL;
688

689 //En caso de ser 0 se agrega el elemento a Head y Tail


690 //Ya que seria el primer y ultimo elemento (o poder agregar mas)
691 if(Q->Size == 0){
692

693 Q->Head = item;


694 Q->Tail = item;
695 }
696 else{
697

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

705 return TRUE;


706 }
707

708 //Funcion para eliminar elemento de la cola


709 Nodo_Q *DeQueueQ(Queuei *Q){
710

711 //Inicializacion
712 Nodo_Q *item;
713

714 //Si esta vacia la cola


715 if(isEmpty(Q)){
716

717 return 0;
718 }
719 else{
720

721 //Se elimina el elemento


722 item = Q->Head;
723

724 //Reasignacion de Head


725 Q->Head = (Q->Head)->prev;
726

727 //Size disminuye


728 Q->Size--;
729

730 printf("\nSe ha eliminado el primer elemento de la cola");


731 return item;
732 }
733

734 }
735

736 //En caso de estar Vacia la cola


737 int isEmpty(Queuei *Q){
738

739 if(Q == 0){


740

741 printf("\nNo se creo bien la cola");


742 return FALSE;
743 }
744

745 if(Q->Size == 0){


746

135
747 printf("\nNo hay elementos en la cola.");
748 return TRUE;
749 }
750 else{
751

752 return FALSE;


753 }
754 }
755

756

757 //Imprimir Cola


758 void DisplayQ(){
759

760 printf("\n\nImprimiendo cola...");


761

762 if(Queue->Head != 0){


763

764 printf("\nLa cola no esta vacia.");


765

766 Nodo_Q *QH = Queue->Head;


767 Nodo_Q *QT = Queue->Tail;
768 Nodo_Q *Aux = QT->prev;
769

770 printf("\nPrimer elemento de la cola: | %c | --> ",


QH->Data->Vertice);
771

772 if(Aux != 0){


773

774 printf("OKK ");


775 //printf("| %c | -->", Aux->Data->Vertice);
776 }
777

778 printf("Ultimo elemento de la cola: | %c | -->",


QT->Data->Vertice);
779 }
780 else{
781

782 printf("\nLa cola esta vacia.");


783 }
784

785 return;
786 }
787

788 //Recorre la lista de Adj en busca de adjs


789 Nodo_Ver *RecorreML(MLista *A, char *V){
790

791 //Inicializacion
792 int i;
793 Nodo_Ver *NV = 0;
794

136
795 for(i = 0; i < NumV; i++){
796

797 if(Array[i].Vertice == V){


798

799 //Inicializacion
800 Nodo_Ver *apH = Array[i].Head;
801 Nodo_Ver *aux = Array[i].Tail;
802

803 while(apH->Next != aux){


804

805 printf("\nTiene un elemento");


806 NV = apH->Next;
807 apH = apH->Next;
808 return NV;
809 }
810

811 }
812

813 }
814

815 }
816

817 /*Recorridos DFS y BFS*/


818 void BFS(MLista *A, unsigned PO){
819

820

821 //Inicializacion
822 unsigned i;
823 int Q, Q1;
824 Nodo_Q *item = 0;
825 Nodo_Q *Del = 0;
826

827 for(i = 0; i < NumV; i++){


828

829 if(i != PO){


830

831 Color[i] = White;


832 Fathersuki[i] = -1;
833 Distancia[i] = -1;
834 }
835 }
836

837 //Cambiamos los valores del Vertice que se escogio


838 Color[PO] = Gray;
839 Fathersuki[PO] = NULL;
840 Distancia[PO] = 0;
841

842 //Cola inicializada en 0 eleemntos


843 Queue = CreaQ(NumV);
844

137
845 //Creamos un elemento tipo Nodo_Q* con los datos de Vertice de inicio
846 item = SelecVML(Array, PO);
847

848 //Lo metemos a la cola


849 Q1 = Enqueue(Queue, item);
850

851 //Impimimos para comprobar


852 printf("\nPrimer elemento en la cola:");
853 DisplayQ();
854

855 if( (Q = isEmpty(Queue)) == 1){


856

857 printf("\nCola vacia.");


858

859 }
860 else{
861

862 printf("\nNo esta vacia");


863 }
864

865

866 if(Queue != 0){


867

868 //Incializacion
869 int i;
870 char *V = 0;
871 unsigned U;
872 int u;
873

874 //Lo sacamos de la cola


875 Del = DeQueueQ(Queue);
876

877 //Copiamos el vertice en V


878 V = Del->Data->Vertice;
879 U = Del->Data->Numseq;
880 u = Distancia[PO];
881

882 printf("\nVertice u: %c", V);


883 printf("\nPosicion de Vertice u: %u", U);
884 printf("\nDistancia de Vertice u: %d", u);
885

886 //Guardamos los Adj del Vertice


887

888

889 //for(i = 0; i < NumV; i++){


890

891 if(Array[i].Vertice == V){


892

893 //Inicializacion
894 Nodo_Ver *apH = Array[i].Head;

138
895 Nodo_Ver *aux = Array[i].Tail;
896 unsigned Poss;
897

898 while(apH->Next != aux){


899

900 //Inicializacion
901 Nodo_Ver *NV = 0;
902

903

904

905 printf("\nTiene un elemento");


906 NV = apH->Next;
907 Poss = apH->Next->Numseq;
908 printf("\nVertice: %c", NV->Vertice);
909 printf("\nPosicion: %u", Poss);
910

911 /*
912 if( Color[Poss] == White){
913

914 //Inicializacion
915 int Qq;
916 Nodo_Q *Nitem = 0;
917

918 //Cambiamos los valores del Vertice que se escogio


919 Color[Poss] = Gray;
920 Fathersuki[Poss] = U;
921 Distancia[Poss] = u + 1;
922

923 //Imprimimos el primer cambio cuando se pasa de


White a Gray
924 printf("\nCambio de White a Gray del Vertice
%u\n", Poss);
925 ImprimeArrayC(Color);
926 ImprimeArrayF(Fathersuki);
927 ImprimeArrayD(Distancia);
928

929 //Creamos un elemento tipo Nodo_Q* con los datos


de Vertice de inicio
930 Nitem = SelecVML(Array, Poss);
931

932 //Lo metemos a la cola


933 Qq = Enqueue(Queue, Nitem);
934

935 //Otra vez metemos un elemento a la cola vacia


936 DisplayQ();
937

938 //Volvemos el color de U negro


939 Color[U] = Black;
940

941 //Imprimimos ultimo cambio de Gray a Black

139
942 printf("\nCambio de Gray a Black del Vertice
%u\n", Poss);
943 ImprimeArrayC(Color);
944 ImprimeArrayF(Fathersuki);
945 ImprimeArrayD(Distancia);
946

947 printf("\nPROCESO DE ENCOLAMIENTO TERMINADO\n");


948 }
949

950 */
951

952 //Para recorrerse al siguiente Adj


953 apH = apH->Next;
954

955 //Actualizamos U y u (Posicion del padre y distnacia


del padre)
956 //
957 u = u + 1;
958

959 }
960

961 //Se actualiza la posicion del padre


962 U = Poss;
963

964 }
965

966 //}
967

968 printf("\nTermino BFS");


969 }
970

971

972 if( (Q = isEmpty(Queue)) == 1){


973

974 printf("\nCola vacia.");


975

976 }
977 else{
978

979 printf("\nNo esta vacia");


980 }
981

982 //Ahora metemos el elemento a la cola (Necesitamos copiar el Vertice


MLista a otro MLista)
983 //Buscamos el elemento pero esta vez regresamos MLista
984

985

986

987 return;
988 }

140
989

990 //
991

992 //Imprime Arreglo de Distancia


993 void ImprimeArrayD(int *D){
994

995 //Inicializacion
996 int i;
997

998 for(i = 0; i < NumV; i++){


999

1000

1001 printf("| Distancia V%d = %d | ", i, D[i]);


1002

1003

1004 }
1005

1006 return;
1007 }
1008

1009 //Imprime Arreglo del Color


1010 void ImprimeArrayC(int *C){
1011

1012 //Inicializacion
1013 int i;
1014

1015 for(i = 0; i < NumV; i++){


1016

1017 printf("| Color del V%d = %d | ", i, C[i]);


1018

1019 }
1020

1021 printf("\n\n");
1022 return;
1023 }
1024

1025 //Imprime Arreglo de Padres


1026 void ImprimeArrayF(int *F){
1027

1028 //Inicializacion
1029 int i;
1030

1031 for(i = 0; i < NumV; i++){


1032

1033 printf("| Padre de V%d = %d | ", i, F[i]);


1034 }
1035

1036 printf("\n\n");
1037 return;
1038 }

141
142
3.2.3 Entradas

3.2.4 Salidas

3.2.5 Link del Programa


Para consulta puede ingresar al siguiente link para verificar el programa: https:
//code.hackerearth.com/5dcd1dK

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.

Figure 26: Esquema de un arbol y recorrido mı́nimo.

¿Qué es un árbol de expansión?


Dado un gráfico no dirigido y conectado G = (V, E), un árbol de expansión del
gráfico G es un árbol que se extiende G (es decir, incluye todos los vértices de
G) y es un subgrafo de G (cada borde en el árbol pertenece a G).

¿Qué es la expansión mı́nima?


El algoritmo del árbol de expansión mı́nima es un modelo de optimización de
redes que consiste en enlazar todos los nodos de la red de forma directa y/o
indirecta con el objetivo de que la longitud total de los arcos o ramales sea
mı́nima (entiéndase por longitud del arco una cantidad variable según el con-
texto operacional de minimización, y que puede bien representar una distancia
o unidad de medida).

Figure 27: Recorrido mı́nimo.

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.

Pasos para el Algoritmo del árbol de expansión mı́nima:

1. N=1,2,3,. . . ,n el conjunto de nodos de la red.

2. Ck = Conjunto de nodos que se han enlazado de forma permanente en la


iteración k ).
3. Čk= 1,2,3,. . . ,n Conjunto de nodos que hacen falta por enlazarse de forma
permanente.

Paso 0: Conceptualización del Algoritmo

Se definen los conjuntos iniciales C0 = ø que corresponde al conjunto de nodos


enlazados de forma permanente en la iteración indicada en el subı́ndice y Č0 =
N = 1,2,3,4,5,6,7,8 que corresponde al conjunto de nodos pendientes por enlazar
de manera permanente en la iteración indicada en el subı́ndice.

Paso 1:

Se debe definir de manera arbitraria el primer nodo permanente del conjunto


Č0, en este caso escogeremos el nodo 1 (puede ser cualquier otro), que alge-
braicamente se representa con la letra i, se procede a actualizar los conjuntos
iniciales, por ende, C1 = i = 1 y Č0 = N - i = 2,3,4,5,6,7,8, actualizamos k por
ende ahora será igual a 2.

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.

Pasos de Función del Algoritmo:


1. Se marca un vértice cualquiera. Será el vértice de partida.

2. Se selecciona la arista de menor peso incidente en el vértice seleccionado


anteriormente y se selecciona el otro vértice en el que incide dicha arista.
3. Repetir el paso 2 siempre que la arista elegida enlace un vértice selec-
cionado y otro que no lo esté. Es decir, siempre que la arista elegida no
cree ningún ciclo.

4. El árbol de expansión mı́nima será encontrado cuando hayan sido selec-


cionados todos los vértices del grafo.

146
147
3.4.1 Código

Listing 8: Programa en C de Kruscal


1 // Declaraciones en el archivo .h
2 int cn; //cantidad de nodos
3 vector< vector<int> > ady; //matriz de adyacencia
4 // Devuelve la matriz de adyacencia del arbol minimo.
5 vector< vector<int> > Grafo :: kruskal(){
6 vector< vector<int> > adyacencia = this->ady;
7 vector< vector<int> > arbol(cn);
8 vector<int> pertenece(cn); // indica a que arbol pertenece el nodo
9

10 for(int i = 0; i < cn; i++){


11 arbol[i] = vector<int> (cn, 0);
12 pertenece[i] = i;
13 }
14 int nodoA;
15 int nodoB;
16 int arcos = 1;
17 while(arcos < cn){
18 // Encontrar el arco minimo que no forma ciclo y guardar los
nodos y la distancia.
19 int min = INF;
20 for(int i = 0; i < cn; i++)
21 for(int j = 0; j < cn; j++)
22 if(min > adyacencia[i][j] && adyacencia[i][j]!=0 &&
pertenece[i] != pertenece[j]){
23 min = adyacencia[i][j];
24 nodoA = i;
25 nodoB = j;
26 }
27 // Si los nodos no pertenecen al mismo arbol agrego el arco al
arbol minimo.
28 if(pertenece[nodoA] != pertenece[nodoB]){
29 arbol[nodoA][nodoB] = min;
30 arbol[nodoB][nodoA] = min;
31 // Todos los nodos del arbol del nodoB ahora pertenecen al
arbol del nodoA.
32 int temp = pertenece[nodoB];
33 pertenece[nodoB] = pertenece[nodoA];
34 for(int k = 0; k < cn; k++)
35 if(pertenece[k] == temp)
36 pertenece[k] = pertenece[nodoA];
37 arcos++;
38 }
39 }
40 return arbol;
41 }

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.

En otras palabras, el algoritmo encuentra un subconjunto de aristas que for-


man un árbol con todos los vértices, donde el peso total de todas las aristas en
el árbol es el mı́nimo posible. Si el grafo no es conexo, entonces el algoritmo
encontrará el árbol recubridor mı́nimo para uno de los componentes conexos
que forman dicho grafo no conexo.

149
Listing 9: Programa en C de Prim
1 //**** Comienza Archivo grafo.h *****//
2 #include <vector>
3

4 using namespace std;


5 class Grafo
6 {
7 public:
8 Grafo();
9 Grafo(int nodos);
10 vector< vector<int> > prim();
11 private:
12 const int INF = numeric_limits<int>::max();
13 int cn; //cantidad de nodos
14 vector< vector<int> > ady; //matriz de adyacencia
15 };
16 //**** Finaliza Archivo grafo.h *****//
17

18

19 //**** Comienza Archivo grafo.cpp *****//


20 Grafo::Grafo()
21 {
22 }
23

24 Grafo::Grafo(int nodos)
25 {
26 this->cn = nodos;
27 this->ady = vector< vector<int> > (cn);
28

29 for(int i = 0; i < cn; i++)


30 ady[i] = vector<int> (cn, INF);
31 }
32

33 vector< vector<int> > Grafo :: prim(){


34 // uso una copia de ady porque necesito eliminar columnas
35 vector< vector<int> > adyacencia = this->ady;
36 vector< vector<int> > arbol(cn);
37 vector<int> markedLines;
38 vector<int> :: iterator itVec;
39

40 // Inicializo las distancias del arbol en INF.


41 for(int i = 0; i < cn; i++)
42 arbol[i] = vector<int> (cn, INF);
43

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

53 // Encuentro la menor distancia entre las filas marcadas.


54 // El nodo padre es la linea marcada y el nodo hijo es la
columna del minimo.
55 int min = INF;
56 for(itVec = markedLines.begin(); itVec != markedLines.end();
itVec++)
57 for(int i = 0; i < cn; i++)
58 if(min > adyacencia[*itVec][i]){
59 min = adyacencia[*itVec][i];
60 padre = *itVec;
61 hijo = i;
62 }
63

64 arbol[padre][hijo] = min;
65 arbol[hijo][padre] = min;
66 }
67 return arbol;
68 }
69 //**** Finaliza Archivo grafo.cpp *****//

151

También podría gustarte