-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlist.c
141 lines (122 loc) · 2.85 KB
/
list.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
/* Fernando Camussi
fcamussi@gmail.com */
#include "list.h"
#include <stdlib.h>
/*
Crea una lista
Si circular = 1 se comporta como una lista circular (round robin),
si circular = 0 se comporta como una lista enlazada normal y puede
usarse como una cola
*/
void list_create(list_t *list, uint8_t circular)
{
list->circular = circular;
list->first = NULL;
list->last = NULL;
list->current = NULL;
}
/*
Libera la memoria usada por una lista
*/
void list_destroy(list_t *list)
{
node_t *node, *tmp;
node = list->first;
while (node != list->last)
{
tmp = node;
node = node->next;
free(tmp);
}
free(node);
}
/*
Agrega un elemento al final de una lista
*/
void list_append(list_t *list, void *element)
{
node_t *node;
node = (node_t *)malloc(sizeof(node_t));
node->element = element;
if (list->last)
{
list->last->next = node;
}
else
{
list->first = node;
list->current = node;
}
list->last = node;
node->next = (list->circular ? list->first : NULL);
}
/*
Remueve el primer elemento de una lista
Se asume que la lista no está vacía
*/
void list_remove_first(list_t *list)
{
node_t *tmp;
tmp = list->first;
if (list->first == list->last) // hay un solo nodo
{
list->first = list->last = list->current = NULL;
}
else // hay más de un nodo
{
if (list->current == list->first)
{
list->current = list->first->next;
}
list->first = list->first->next;
if (list->circular) list->last = list->first;
}
free(tmp);
}
/*
Remueve un elemento de una lista
Se asume que el elemento está en la lista
Si el elemento aparece varias veces se remueve solo
la primer ocurrencia
*/
void list_remove(list_t *list, void *element)
{
node_t *node, *tmp;
if (list->first == list->last) // hay un solo nodo
{
tmp = list->first;
list->first = list->last = list->current = NULL;
}
else // hay más de un nodo
{
if (list->first->element == element) // es el primero
{
tmp = list->first;
list->first = list->first->next;
if (list->circular) list->last->next = list->first;
if (tmp == list->current)
{
list->current = list->first;
}
}
else
{
node = list->first;
while (node->next->element != element)
{
node = node->next;
}
tmp = node->next;
if (tmp == list->last)
{
list->last = node;
}
node->next = node->next->next;
if (tmp == list->current)
{
list->current = node;
}
}
}
free(tmp);
}