-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlist.c
117 lines (92 loc) · 2.34 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
/* list.c */
#include <stdlib.h>
#include <string.h>
#include "list.h"
/* list_init */
void list_init(List *list, void (*destroy)(void *data)) {
/* Initialize the list */
list->size = 0;
list->destroy = destroy;
list->head = NULL;
list->tail = NULL;
return;
}
/* list_destroy */
void list_destroy(List *list) {
void *data;
/* Remove each element. */
while (list_size(list) > 0) {
if (list_rem_next(list, NULL, (void *)&data) == 0
&& list->destroy != NULL) {
list->destroy(data);
}
}
/* No operations are allowed now, but clear the structure
* as a precaution. */
memset(list, 0, sizeof(List));
return;
}
/* list_ins_next */
int list_ins_next(List *list, ListElmt *element, const void *data) {
ListElmt *new_element;
/* Allocate storage for the element. */
if ((new_element = (ListElmt *)malloc(sizeof(ListElmt))) == NULL) {
return -1;
}
/* Insert the element into the list. */
new_element->data = (void *)data;
if (element == NULL) {
/* Handle insertion at the head of the list. */
if (list_size(list) == 0) {
list->tail = new_element;
}
new_element->next = list->head;
list->head = new_element;
}
else {
/* Handle insertion somewhere other than at the head. */
if (element->next == NULL) {
list->tail = new_element;
}
new_element->next = element->next;
element->next = new_element;
}
/* Adjust the size of list to accout for the inserted element. */
list->size++;
return 0;
}
/* list_rem_next */
int list_rem_next(List *list, ListElmt *element, void **data) {
ListElmt *old_element;
/* Don't allow removal from an empty list. */
if (list_size(list) == 0) {
return -1;
}
/* Remove the element from the list. */
if (element == NULL) {
/* Handle the removal from the head of list. */
*data = list->head->data;
old_element = list->head;
list->head = list->head->next;
if (list_size(list) == 1) {
list->tail == NULL;
}
}
else {
/* Handle removal somewhere other than at the head. */
if (element->next == NULL) {
return -1;
}
*data = element->next->data;
old_element = element->next;
element->next = element->next->next;
if (element->next == NULL) {
list->tail = element;
}
}
/* Free the storage allocated by the abstract datatype. */
free(old_element);
/* Adjust the size of the list to accout for the removal element. */
list->size--;
return 0;
}