forked from dxtr/list
-
Notifications
You must be signed in to change notification settings - Fork 0
/
list.c
142 lines (129 loc) · 3.27 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
140
141
#include <stdlib.h>
#include <string.h>
#include "list.h"
/* Creates a list (node) and returns it
* Arguments: The data the list will contain or NULL to create an empty
* list/node
*/
list_node* list_create(void *data)
{
list_node *l = malloc(sizeof(list_node));
if (l != NULL) {
l->next = NULL;
l->data = data;
}
return l;
}
/* Completely destroys a list
* Arguments: A pointer to a pointer to a list
*/
void list_destroy(list_node **list)
{
if (list == NULL) return;
while (*list != NULL) {
list_remove(list, *list);
}
}
/* Creates a list node and inserts it after the specified node
* Arguments: A node to insert after and the data the new node will contain
*/
list_node* list_insert_after(list_node *node, void *data)
{
list_node *new_node = list_create(data);
if (new_node) {
new_node->next = node->next;
node->next = new_node;
}
return new_node;
}
/* Creates a new list node and inserts it in the beginning of the list
* Arguments: The list the node will be inserted to and the data the node will
* contain
*/
list_node* list_insert_beginning(list_node *list, void *data)
{
list_node *new_node = list_create(data);
if (new_node != NULL) { new_node->next = list; }
return new_node;
}
/* Creates a new list node and inserts it at the end of the list
* Arguments: The list the node will be inserted to and the data the node will
* contain
*/
list_node* list_insert_end(list_node *list, void *data)
{
list_node *new_node = list_create(data);
if (new_node != NULL) {
for(list_node *it = list; it != NULL; it = it->next) {
if (it->next == NULL) {
it->next = new_node;
break;
}
}
}
return new_node;
}
/* Removes a node from the list
* Arguments: The list and the node that will be removed
*/
void list_remove(list_node **list, list_node *node)
{
list_node *tmp = NULL;
if (list == NULL || *list == NULL || node == NULL) return;
if (*list == node) {
*list = (*list)->next;
free(node);
node = NULL;
} else {
tmp = *list;
while (tmp->next && tmp->next != node) tmp = tmp->next;
if (tmp->next) {
tmp->next = node->next;
free(node);
node = NULL;
}
}
}
/* Removes an element from a list by comparing the data pointers
* Arguments: A pointer to a pointer to a list and the pointer to the data
*/
void list_remove_by_data(list_node **list, void *data)
{
if (list == NULL || *list == NULL || data == NULL) return;
list_remove(list, list_find_by_data(*list, data));
}
/* Find an element in a list by the pointer to the element
* Arguments: A pointer to a list and a pointer to the node/element
*/
list_node* list_find_node(list_node *list, list_node *node)
{
while (list) {
if (list == node) break;
list = list->next;
}
return list;
}
/* Finds an elemt in a list by the data pointer
* Arguments: A pointer to a list and a pointer to the data
*/
list_node* list_find_by_data(list_node *list, void *data)
{
while (list) {
if (list->data == data) break;
list = list->next;
}
return list;
}
/* Finds an element in the list by using the comparison function
* Arguments: A pointer to a list, the comparison function and a pointer to the
* data
*/
list_node* list_find(list_node *list, int(*func)(list_node*,void*), void *data)
{
if (!func) return NULL;
while(list) {
if (func(list, data)) break;
list = list->next;
}
return list;
}