aboutsummaryrefslogtreecommitdiff
path: root/src/linked_list.c
blob: 6335c3dd2ac672e412203a8a5e6d1146d710bd96 (plain)
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
#include "linked_list.h"
#include <stdlib.h>

LinkedList *linked_list_new(void) {
    /* Note that the members of the linked list
     * is initialized to 0 when using calloc() */
    LinkedList *ll = (LinkedList *)calloc(1, sizeof(LinkedList));
    if (!ll)
        return NULL;
    return ll;
}

void linked_list_delete(LinkedList *ll) {
    LinkedListNode *node = ll->head;
    LinkedListNode *next;

    while (node) {
        next = node->next;
        free(node);
        node = next;
    }

    free(ll);
}

LinkedListNode *linked_list_append(LinkedList *ll, void *elem) {
    LinkedListNode *new_node = calloc(1, sizeof(LinkedListNode));
    if (!new_node)
        return NULL;
    new_node->data = elem;

    if (!ll->head) {
        new_node->prev = NULL;
        ll->head = new_node;
        ll->tail = new_node;
    } else {
        new_node->prev = ll->tail;
        ll->tail->next = new_node;
        ll->tail = new_node;
    }

    ll->size++;
    return new_node;
}

void *linked_list_popfront(LinkedList *ll) {
    if (!ll->head)
        return NULL;

    void *elem = ll->head->data;
    LinkedListNode *node = ll->head;
    ll->head = ll->head->next;

    ll->size--;
    free(node);
    return elem;
}

LinkedListNode *linked_list_find(LinkedList *ll, void *elem) {
    if (!ll->head)
        return NULL;

    LinkedListNode *node = ll->head;
    while (node) {
        /* !NOTE should use a given comparator function
         * instead of '==' operator */
        if (node->data == elem)
            return node;
        node = node->next;
    }

    return NULL; // Couldn't find the element
}

void *linked_list_remove(LinkedList *ll, LinkedListNode *node) {
    void *elem = node->data;

    if (node->prev)
        node->prev->next = node->next;
    else
        ll->head = node->next;

    if (node->next)
        node->next->prev = node->prev;
    else
        ll->tail = node->prev;

    free(node);
    ll->size--;
    return elem;
}