diff options
Diffstat (limited to 'src/01/02b/doubly_linked_list.c')
| -rw-r--r-- | src/01/02b/doubly_linked_list.c | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/src/01/02b/doubly_linked_list.c b/src/01/02b/doubly_linked_list.c new file mode 100644 index 0000000..88e49ee --- /dev/null +++ b/src/01/02b/doubly_linked_list.c @@ -0,0 +1,112 @@ +#include "doubly_linked_list.h" +#include <stdio.h> +#include <stdlib.h> + +Node *initialize(int data) { + Node *node = malloc(sizeof(Node)); + node->data = data; + node->next = NULL; + node->prev = NULL; + return node; +} + +Node *add(Node *head, int data) { + Node *tail; + Node *tmp = head; + + while(tmp) { + if (!tmp->next) + break; + tmp = tmp->next; + } + tail = tmp; + tail->next = initialize(data); + tail->next->prev = tail; + return tail->next; +} + +Node *get(Node *from, int index) { + if (!from || index < 0) return NULL; + + while(index > 0 && from){ + from = from->next; + index--; + } + return from; +} + +static int size(Node *head) { + int i = 0; + for (Node *tmp = head; tmp && tmp != NULL; tmp = tmp->next) i++; + return i; +} + +static void assign_next(Node *self, Node *other) { + if (self) + self->next = other; + + if (other) + other->prev = self; +} + +static void assign_prev(Node *self, Node *other) { + if (self) + self->prev = other; + + if (other) + other->next = self; +} + +void swap(Node *x, Node *y) { + if (x == y) return; + if (!x || !y) return; + if (x->prev == y && y->next == x) return swap(y, x); + + Node *xp = x->prev, *xn = x->next, *yp = y->prev, *yn = y->next; + + // if adjacent + if (x->next == y && y->prev == x) { + assign_next(x, yn); + assign_prev(x, y); + assign_prev(y, xp); + } else { + assign_prev(x, yp); + assign_next(x, yn); + assign_prev(y, xp); + assign_next(y, xn); + } +} + +Node *reverse(Node *head) { + Node *tmp = NULL; + Node *current = head; + + while (current != NULL) { + tmp = current->prev; + current->prev = current->next; + current->next = tmp; + current = current->prev; + } + return tmp ? tmp->prev : head; +} + +static void print(Node *node) { + if (node->prev && node->next) + printf("%d <- %d -> %d\n", node->prev->data, node->data, node->next->data); + else if (node->next) + printf("nil <- %d -> %d\n", node->data, node->next->data); + else + printf("%d <- %d -> nil\n", node->prev->data, node->data); +} + +static void inspect(Node *node) { + if (!node) return; + + printf("*******\n"); + while (node) { + print(node); + node = node->next; + } + printf("*******\n"); +} + |
