Skip to main content
1 of 6
Chris
  • 4.7k
  • 1
  • 7
  • 37

Several valid critiques have been offered, but I have not yet seen a design suggestion that stands to greatly increase the complexity of a common list operation: appending to the end of a list.

Currently you have to traverse the whole list to find the last node, then attach a new node to that. However, since a list is separate from the internal nodes, in addition to a head node, your list can contain a link to the tail node.

With this in mind, the code might look something like:

typedef struct Node {
    struct Node* next;
    int data;
} Node;

typedef struct LinkedList {
    Node* head;
    Node* tail;
    int length;
} LinkedList;

LinkedList* append(LinkedList* list, int data) {
    // Checks on validity of list and its pointers.

    Node* new_node = malloc(sizeof Node);
    if (!new_node) return NULL;

    new_node->next = NULL;
    new_node->data = data;

    list->tail->next = new_node;
    list->tail = new_node;
    list->length++;

 
    return list;
}

Appending now becomes a O(1) operation rather than O(n), and helps you avoid the fact that _add_node, which append calls is recursive rather than iterative. Now, it's tail-recursive, which is good, but you can't count on C compilers to optimize for this, and you're opening yourself up to the possibility of a stack overflow on a long list.

Chris
  • 4.7k
  • 1
  • 7
  • 37