diff options
Diffstat (limited to 'src/01/05/doubly_linked_list.c')
| -rw-r--r-- | src/01/05/doubly_linked_list.c | 127 |
1 files changed, 108 insertions, 19 deletions
diff --git a/src/01/05/doubly_linked_list.c b/src/01/05/doubly_linked_list.c index 006b194..307fcb3 100644 --- a/src/01/05/doubly_linked_list.c +++ b/src/01/05/doubly_linked_list.c @@ -1,7 +1,15 @@ #include "doubly_linked_list.h" #include <stdio.h> #include <stdlib.h> +#include <string.h> +/** + * The equivalent of a constructor + * to initialize a new node in a doubly linked list. + * + * @param data The data to initialize the head node with. + * @return new Node bound to the data specified + */ Node *initialize(int data) { Node *node = malloc(sizeof(Node)); node->data = data; @@ -10,21 +18,43 @@ Node *initialize(int data) { return node; } -Node *add(Node *head, int data) { - Node *tail; +/** + * Returns the tail of the list. + * + * @param head The head of the linked list + * @return The tail of the linked list + */ +Node *tail(Node *head) { 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; + return tmp; +} + +/** + * Adds data to the tail of a doubly linked list. + * + * @param head The head of the doubly linked list + * @param data The data to append to the list + * @return Returns the new node. + */ +Node *add(Node *head, int data) { + Node *t = tail(head); + t->next = initialize(data); + t->next->prev = t; + return t->next; } +/** + * Returns a specific node in the list by index starting from 0. + * + * @param from The node to start scanning from. + * @param index The zero based index of the node to retrieve. + * @return The node at the specified index. + */ Node *get(Node *from, int index) { if (!from || index < 0) return NULL; @@ -36,6 +66,12 @@ Node *get(Node *from, int index) { return from; } +/** + * Returns the number of items in the linked list. + * + * @param head The head of the linked list + * @return The number of items in the list. + */ static int size(Node *head) { int i = 0; for (Node *tmp = head; tmp && tmp != NULL; tmp = tmp->next) @@ -43,6 +79,12 @@ static int size(Node *head) { return i; } +/** + * Assigns the next pointer of a node. + * + * @param self The node struct to alter. + * @param other The other node to point to. + */ static void assign_next(Node *self, Node *other) { if (self) self->next = other; @@ -51,6 +93,12 @@ static void assign_next(Node *self, Node *other) { other->prev = self; } +/** + * Assigns the previous pointer of a node. + * + * @param self The node struct to alter. + * @param other The other node to point to. + */ static void assign_prev(Node *self, Node *other) { if (self) self->prev = other; @@ -59,6 +107,12 @@ static void assign_prev(Node *self, Node *other) { other->next = self; } +/** + * Reverses a linked list. + * + * @param head The head of the linked list. + * @return The new head of the linked list. + */ Node *reverse(Node *head) { Node *tmp = NULL; Node *current = head; @@ -72,24 +126,59 @@ Node *reverse(Node *head) { return tmp ? tmp->prev : head; } -static void print(Node *node) { +/** + * Generates a string representation of the Node usable for printing to stdout + * + * @param node The node to represent as a string + * @return The string that represents the node + */ +char *to_s(Node *node) { + const int buffer_size = 32; + char *buffer = malloc(buffer_size); + memset(buffer, buffer_size, '\0'); + if (node->prev && node->next) - printf("(%d<%d>%d)", node->prev->data, node->data, node->next->data); + snprintf(buffer, buffer_size, "(%d<%d>%d) ", node->prev->data, node->data, node->next->data); else if (node->next) - printf("(nil<%d>%d)", node->data, node->next->data); + snprintf(buffer, buffer_size, "(nil<%d>%d) ", node->data, node->next->data); else - printf("(%d<%d>nil)", node->prev->data, node->data); + snprintf(buffer, buffer_size, "(%d<%d>nil) ", node->prev->data, node->data); + return buffer; } -void inspect(Node *node) { - if (!node) - return; +/** + * Prints the previous, data and next pointers for a node + * + * @param node The node to print + */ +static void print(Node *node) { + char *message = to_s(node); + printf("%s", message); + free(message); +} - printf("[ "); - while (node) { - print(node); - printf(" "); - node = node->next; +/** + * Iterates through each node in a linked list. + * + * @param self The node to start iterating from. + * @param block The callback function to invoke on each node. + */ +void each(Node *self, Visitor block) { + Node *tmp = self; + + while (tmp) { + block(tmp); + tmp = tmp->next; } +} + +/** + * Renders a visual output of a full linked list. + * + * @param node The head of the linked list + */ +void inspect(Node *node) { + printf("[ "); + each(node, &print); printf("]\n"); } |
