-
Notifications
You must be signed in to change notification settings - Fork 0
/
list.cpp
137 lines (125 loc) · 2.96 KB
/
list.cpp
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
#include "list.h"
#include <stdlib.h>
List *createList() {
List *new_list = (List*)malloc(sizeof(List));
new_list->head = NULL;
new_list->tail = NULL;
new_list->num_nodes = 0;
return new_list;
}
ListNode *createListNode(void *data) {
ListNode *new_node = (ListNode*)malloc(sizeof(ListNode));
new_node->data = data;
new_node->next = NULL;
new_node->prev = NULL;
return new_node;
}
// free memory allocated for the List
void deleteList(List** list_ptr, deleter delete_fn ) {
if ((list_ptr != NULL) && (*list_ptr != NULL)) {
List *list = *list_ptr;
ListNode *node = list->head;
ListNode *next_node = NULL;
while(node != NULL) {
// save the next node
next_node = node->next;
// hand off node's data to deleter function
if (delete_fn != NULL) {
delete_fn(node->data);
}
free(node);
node = next_node;
}
free(list);
*list_ptr = NULL;
}
}
// Add data to the START of the list
void prependTo(List *list, void *data) {
ListNode *new_node = createListNode(data);
if (list->head == NULL) {
list->tail = new_node;
} else {
new_node->next = list->head;
list->head->prev = new_node;
}
list->head = new_node;
list->num_nodes++;
}
// Add data to the END of the list
void appendTo(List *list, void *data) {
ListNode *new_node = createListNode(data);
if (list->head == NULL) {
list->head = new_node;
} else {
list->tail->next = new_node;
new_node->prev = list->tail;
}
list->tail = new_node;
list->num_nodes++;
}
// get element at index (0-indexed)
void *getElement(List *list, int index) {
if (index >= list->num_nodes) {
return NULL;
}
int i = 0;
ListNode *n = list->head;
while (i++ < index) {
n = n->next;
}
return n->data;
}
// get first element matching comp_op
void *getMatch(List *list, compare comp_op, void *data) {
int i = 0;
ListNode *n = list->head;
while ((n != NULL) && !comp_op(n->data, data) ) {
n = n->next;
}
return (n != NULL? n->data : NULL);
}
void *unlinkElement(List *list, ListNode *element);
// Remove first node that contains the given data
void *removeIfExists(List* list, void* data) {
ListNode *element = list->head;
while ((element != NULL) && (element->data != data)) {
element = element->next;
}
if (element != NULL) {
data = unlinkElement(list, element);
}
return data;
}
// remove element at index (0-indexed)
void *removeElement(List *list, int index) {
void *data = NULL;
if (index >= list->num_nodes) {
return data;
}
ListNode *element = NULL;
int i = 0;
element = list->head;
while (i++ < index) {
element = element->next;
}
data = unlinkElement(list, element);
return data;
}
// remove the given ListNode from the list
void *unlinkElement(List *list, ListNode *element) {
if (element->prev == NULL) {
list->head = element->next;
} else {
element->prev->next = element->next;
}
if (element->next == NULL) {
list->tail = element->prev;
} else {
element->next->prev = element->prev;
}
void *data = element->data;
free(element);
list->num_nodes--;
return data;
}