The Linked List Data Structure

Review of Linked Lists

When dealing with linked lists, it helps to understand what's going on if you draw diagrams.

Some generic "structures" when discussing linked lists:

struct Node
{
  Node *next;  // all node structs have this
  Node *prev;  // some node structs have this (double)
  Data data;   // the payload
};

Node *NewNode(void)
{
  Node *p = new Node;
  p->next = NULL;  
  p->prev = NULL;  // depending on single/double linked list
  return p;
}

Node *FreeNode(Node *node)
{
  // possibly validate the node
  delete node;
}
Some common operations with linked lists: Simple examples:
Node *p1 = NewNode();  // create a new node, possibly initialized
FreeNode(p1);          // freeing a node, possibly returning to free store
Node *head = p1;       // always points to first node (NULL if empty list)
Node *tail = p1;       // always points to last node (NULL if empty list)

Node *p2 = NewNode();  // create new node
tail->next = p2;       // add to end
tail = tail->next;     // update tail

Node *p3 = NewNode();  // create new node
p3->next = head;       // add to front
head = p3;             // update head
Let's follow an example of a singly-linked list. (There is only one Node * in the struct pointing to the next node.)

We can allocate 3 nodes:

Node *n1 = NewNode();
Node *n2 = NewNode();
Node *n3 = NewNode();
A diagram would look like this:

Then, we can "hook" up the nodes:

n1->next = n2;
n2->next = n3;

Node *head = n1;
Resulting in this picture:


Usually, when we are creating linked lists, we create anonymous nodes that can only be accessed from a previous node's next pointer:
Node *head = NULL;
for (int i = 0; i < 3; i++)
{
  Node *temp = NewNode();
  temp->next = head;
  head = temp;
}
The picture below shows the structure after one iteration of the for loop:

A second iteration then produces this:

And the third one results in this:


Inserting a node (after a given node) into a singly-linked list:


Assuming we have a variable named head that is pointing at the front of a singly-linked list, we can write code to manipulate the list. Note that this code just shows the code required to hook up the links. "Real" code would need to do error checking and to free the nodes that have been removed.

This is our new node to be added:

Node *node = NewNode();

When traversing an array, we have this classic code:
// assume we have some array[SIZE]
for (int i = 0; i < SIZE; i++)
  DoSomething(array[i]);
The corresponding classic code for a linked list:
// assume we have a list
Node *t = head;
while (t)
{
  DoSomething(t);
  t = t->next;
}