-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlinkedlist.c
More file actions
308 lines (262 loc) · 5.44 KB
/
linkedlist.c
File metadata and controls
308 lines (262 loc) · 5.44 KB
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
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
#include <stdlib.h> /* malloc/free */
#include <stdio.h> /* printf */
#include "linkedlist.h"
/* head will thus change so return new head */
node_ptr push_front(node_ptr head, node_ptr to_add) {
if(head)
to_add->next = head;
return to_add;
}
/* this is like adding to a queue */
node_ptr push_back(node_ptr head, node_ptr to_add) {
/* go to end of ll and append on end */
if(head) {
node_ptr curr = head;
while(curr->next)
curr = curr->next;
curr->next = to_add;
} else {
printf("push_back - no head element so cannot add\n");
}
return head;
}
/* We add node by num in ascending order */
void add_sorted_node(node_ptr head, node_ptr to_add) {
node_ptr prev = head;
while(head && head->val < to_add->val) {
prev = head;
head = head->next;
}
prev->next = to_add;
to_add->next = head;
}
node_ptr find_by_value(node_ptr head, stackdata value) {
while(head && head->val != value)
head = head->next;
return head;
}
size_t length(node_ptr head) {
size_t len = 0;
while(head){
head = head->next;
++len;
}
return len;
}
node_ptr make_node(stackdata value) {
node_ptr newnode = malloc(sizeof(node));
newnode->val = value;
newnode->next = NULL;
return newnode;
}
void free_list(node_ptr head) {
node_ptr curr = head;
node_ptr next = 0;
while(curr) {
next = curr->next;
free(curr);
curr = next;
}
}
/* return new head */
node_ptr delete_node(node_ptr head, node_ptr to_delete) {
node_ptr orig_head = head;
node_ptr prev = head;
while(head) {
if(head == to_delete) {
prev->next = to_delete->next;
if(orig_head == head)
orig_head = prev->next;
free(to_delete);
return orig_head;
}
prev = head;
head = head->next;
}
return 0;
}
node_ptr get_last_node(node_ptr head) {
while(head) {
if(head->next == NULL)
break;
head = head->next;
}
return head;
}
void printlist(node_ptr head) {
while(head) {
head = head->next;
}
}
/* ex3.1 given ptr to ll, returns 1 if list sorted (asc), otherwise 0 */
int is_sorted(node_ptr head) {
stackdata tmp = 0;
while(head) {
if(head->val >= tmp)
tmp = head->val;
else
return 0;
head = head->next;
}
return 1;
}
/* three tmp variables. current, next, next-next. on each one you simply change next to point to previous
rather than next node
*/
node_ptr reverse_nodes(node_ptr head) {
node_ptr curr = 0, next = 0, nextnext = 0;
if(head == 0)
return head;
/* setup. point curr to start of list. next to next element and re-point next field of first element */
curr = head;
next = head->next;
head->next = 0;
while(next != '\0') {
nextnext = next->next;
next->next = curr; /* point next to previous element */
curr = next; /* move current to be next */
next = nextnext; /* move next to next along */
}
return curr;
}
void reverse_print(node_ptr p) {
if(!p)
return;
reverse_print(p->next);
}
node_ptr reverse_r(node_ptr pivot, node_ptr backward) {
node_ptr rest;
if (pivot == 0)
return backward;
/* flip the head of pivot from forward to backward */
rest = pivot->next;
pivot->next = backward;
/* continue */
return reverse_r(rest, pivot);
}
/* ascending - swaps nodes */
node_ptr selection_sort(node_ptr head)
{
node_ptr p, q, r, s, temp;
p = r = head;
while (p->next != NULL)
{
s = q = p->next;
while (q != NULL)
{
/* left value > right value */
if (p ->val > q->val)
{
if (p->next == q) /* if adjacent nodes */
{
if (p == head) /* special case where we are at head */
{
p->next = q->next;
q->next = p;
/* general swap - could use general swap function */
temp = p;
p = q;
q = temp;
head = p;
r = p;
s = q;
q = q->next;
}
else /* not at head */
{
p->next = q->next;
q->next = p;
r->next = q;
temp = p;
p = q;
q = temp;
s = q;
q = q->next;
}
}
else
{
if (p == head)
{
temp = q->next;
q->next = p->next;
p->next = temp;
s->next = p;
temp = p;
p = q;
q = temp;
s = q;
q = q->next;
head = p;
}
else
{
temp = q->next;
q->next = p->next;
p->next = temp;
r->next = q;
s->next = p;
temp = p;
p = q;
q = temp;
s = q;
q = q->next;
}
}
}
else
{
s = q;
q = q->next;
}
}
r = p;
p = p->next;
}
return head;
}
/* insert n after j - return new ll */
node_ptr insert(node_ptr head, int n, int j) {
node_ptr curr = head, prev = NULL;
node_ptr newnode = make_node(n);
while(curr && j--) {
prev = curr;
curr = curr->next;
}
if(curr) { /* not at end */
if(prev == NULL) {
newnode->next = head;
head = newnode;
} else {
prev->next = newnode;
newnode->next = curr;
}
} else { /* push onto tail */
prev->next = newnode;
}
return head;
}
/* convert n to binary number and store in new ll, least significant bit at head
Just a practice item - not really a generally useful linked list function */
node_ptr insert_binary(int n) {
node_ptr head = NULL, np;
while(n) {
np = make_node(n & 1 ? 1 : 0);
head = push_front(head, np);
n >>= 1;
}
return head;
}
/* convert binary from insert_binary function back to decimal */
unsigned binary2decimal(node_ptr head) {
unsigned tmp, i;
tmp=i=0;
/* reverse list first */
head = reverse_r(head, 0);
while(head) {
tmp += head->val << i;
++i;
head = head->next;
}
return tmp;
}