-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlinked_list.c
161 lines (146 loc) · 4.48 KB
/
linked_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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#include "linked_list.h"
/* - STRUCTS - */
// Contains the data and pointers to its adjacent nodes
struct node {
DATA_TYPE value;
struct node *next, *previous;
};
// The list accessor containing pointers to the first and last nodes
struct list {
struct node *first, *last;
size_t size;
};
/* - PRIVATE FUNCTIONS - */
// only used internally to this .c file. not intended for end user to see.
// Find the fastest route to the index location and travel to node at the index.
// Return a pointer to that node.
Node *node_travel(List *list, size_t index) {
Node *temp;
if (index > list->size / 2) {
temp = list->last;
for (int i = list->size - index - 1; i > 0; i--) {
temp = temp->previous;
}
} else {
temp = list->first;
for (int i = index; i > 0; i--) {
temp = temp->next;
}
}
return temp;
}
// Use in the bubble sort algorithm to swap the values held by two nodes.
void value_swap(DATA_TYPE *a, DATA_TYPE *b) {
DATA_TYPE temp = *a;
*a = *b;
*b = temp;
return;
}
/* - LIST FUNCTIONS - */
// Return a pointer to a new list accessor
List *make_list() {
List *list = (List *)malloc(sizeof(List));
if (!list) return NULL;
list->first = list->last = NULL;
list->size = 0;
return list;
}
// Add a node at the end of the list with the given value
bool list_add(List *list, DATA_TYPE value) {
if (!list) return false;
Node *node = (Node *)malloc(sizeof(Node));
if (!node) return false;
// set node values
node->value = value;
node->previous = list->last;
node->next = NULL;
// update list values
if (list->size) {
list->last->next = node;
} else {
list->first = node;
}
list->last = node;
list->size++;
return true;
}
// Insert a node into the list at the given index with the given value.
bool list_insert(List *list, DATA_TYPE value, size_t index) {
if (!list || index > list->size) return false;
if (!list->size || list->size == index) {
return list_add(list, value);
}
Node *node = (Node *)malloc(sizeof(Node));
if (!node) return false;
// find fastest route to the index location and travel to node currently at
// the index
Node *temp = node_travel(list, index);
// set node values
node->value = value;
node->previous = temp->previous;
node->next = temp;
// insert node into the list structure:
node->previous->next = node;
node->next->previous = node;
// increase list size
list->size++;
// done
return true;
}
// Remove the node at the given index and frees its memory
bool list_remove(List *list, size_t index) {
if (!list || index >= list->size) return false;
// find fastest route to the index location and travel to node currently at
// the index
Node *temp = node_travel(list, index);
// reconnect list to bypass the node being removed
temp->next->previous = temp->previous;
temp->previous->next = temp->next;
// free the node and decrement the list size
free(temp);
list->size--;
return true;
}
// Return the number of elements in the list
int list_size(List *list) {
return list ? list->size : -1;
}
// need to set up error handling for this. right now returns 0 on error which
// falsely indicates an empty list when the list might be NULL or index invalid
// Return the value held at the given index
DATA_TYPE list_get_value(List *list, size_t index) {
if (!list || index >= list->size) return (DATA_TYPE)0;
return node_travel(list, index)->value;
}
// Free all of the list's memory including all of its nodes' memory
bool destroy_list(List *list) {
if (!list) return false;
Node *temp = list->first;
Node *temp_next = temp;
while (temp) {
temp_next = temp->next;
free(temp);
temp = temp_next;
}
free(list);
return true;
}
/* - SORT FUNCTIONS - */
// Perform a bubble sort algorithm on the list to order its values low to high
bool list_bubble_sort(List *list) {
if (!list) return false;
Node *current;
int max_unsorted_index;
for (int i = list->size; i > 1; i = max_unsorted_index) {
max_unsorted_index = 0;
current = list->first;
for (int j = 1; j < i; j++) {
if (current->value > current->next->value) {
value_swap(¤t->value, ¤t->next->value);
max_unsorted_index = j;
}
current = current->next;
}
}
return true;
}