-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathglist.c
144 lines (110 loc) · 2.94 KB
/
glist.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#include "glist.h"
#include <stdlib.h>
#include <string.h>
#include "util.h"
GList glist_crear() { return NULL; }
void glist_destruir(GList lista, FDestructora destruir) {
GNodo *nodoAEliminar;
GNodo *inicio = lista;
do {
nodoAEliminar = lista;
destruir(nodoAEliminar->dato);
lista = lista->sig;
free(nodoAEliminar);
} while (lista != inicio);
}
int glist_vacia(GList lista) { return lista == NULL; }
GList glist_agregar_inicio(GList lista, void *dato) {
GNodo *nuevoNodo = malloc(sizeof(GNodo));
nuevoNodo->dato = dato;
if (glist_vacia(lista)) {
nuevoNodo->sig = nuevoNodo->ant = nuevoNodo;
return nuevoNodo;
}
nuevoNodo->sig = lista;
nuevoNodo->ant = lista->ant;
lista->ant = nuevoNodo;
nuevoNodo->ant->sig = nuevoNodo;
return nuevoNodo;
}
GList glist_agregar_final(GList lista, void *dato) {
GNodo *nuevoNodo = malloc(sizeof(GNodo));
nuevoNodo->dato = dato;
if (glist_vacia(lista)) {
nuevoNodo->sig = nuevoNodo->ant = nuevoNodo;
return nuevoNodo;
}
nuevoNodo->sig = lista;
nuevoNodo->ant = lista->ant;
lista->ant = nuevoNodo;
nuevoNodo->ant->sig = nuevoNodo;
return lista;
}
void glist_recorrer(GList lista, FVisitante visitar) {
GNodo *nodo = lista;
do {
visitar(nodo->dato);
nodo = nodo->sig;
} while (nodo != lista);
}
int glist_longitud(GList lista) {
int longitud = 0;
GNodo *nodo = lista;
do {
longitud++;
nodo = nodo->sig;
} while (nodo != lista);
return longitud;
}
void *glist_dato_random(GList lista) {
int tamano = glist_longitud(lista);
int indice = rand() % tamano;
GNodo *nodo = lista;
if (indice < tamano / 2) {
for (int i = 0; i < indice; i++) nodo = nodo->sig;
} else {
for (int i = 0; i < indice; i++) nodo = nodo->ant;
}
return nodo->dato;
}
GList glist_desde_archivo(char *nombre, int permitirSimbolos) {
FILE *archivo = fopen(nombre, "r");
if (archivo == NULL) return NULL;
GList lista = glist_crear();
char *linea;
while ((linea = get_line(archivo, permitirSimbolos)) != NULL) {
lista = glist_agregar_inicio(lista, linea);
}
fclose(archivo);
return lista;
}
void glist_a_archivo(GList lista, char *nombre, FEscritora escribir) {
FILE *archivo;
archivo = fopen(nombre, "w+");
GNodo *nodo = lista;
do {
escribir(nodo->dato, archivo);
nodo = nodo->sig;
} while (nodo != lista);
fclose(archivo);
}
GList glist_map(GList lista, FMap f, FCopiadora copiar) {
GList nuevaLista = glist_crear();
GNodo *nodo = lista;
do {
void *dato = copiar(nodo->dato);
nuevaLista = glist_agregar_final(nuevaLista, f(dato));
nodo = nodo->sig;
} while (nodo != lista);
return nuevaLista;
}
GList glist_filter(GList lista, FPredicado p, FCopiadora copiar) {
GList nuevaLista = glist_crear();
GNodo *nodo = lista;
do {
if (p(nodo->dato))
nuevaLista = glist_agregar_final(nuevaLista, copiar(nodo->dato));
nodo = nodo->sig;
} while (nodo != lista);
return nuevaLista;
}