20070202

linked lists

What does this statement mean?
current = current->next;


It means that you have a structure named current, which has an attribute called next, which is of the same type as current itself. The programmer instructs the machine to use next in place of current from here on.
Typically this statement is used to realize linked lists. These work like this: The programmer creates a couple of these structs and gives each the data we actually care about and information about the next element in line.
For example, consider a list of people: John, Frank, Alice, Jennifer. In order to find all four of these, it is sufficient to remember that John was the first one in our list and to tell John to remember Frank, Frank to remember Alice and Alice to remember Jennifer. Now if we want to list the age of all four of them it is enough to call up John, ask him how old he is and who was the next in line and repeat this until Jennifer tells us that there was no one next.

To realize this example as a program, we first need a data structure, which can hold our friends and a link to the next in line. (For simplicity we will only save the name of each in the data structure, more information would be trivial to add):
struct friendList {
char *name;
struct friendList *next;
};


To iterate through them the following will work:
struct friendList *current = john;
while(current != NULL)
{
printf("%s\n", current->name);
current = current->next;
}



Here is the example in full:

#include <stdio.h>
#include <stdlib.h>

struct friendList {
char *name;
struct friendList *next;
};


int main(int argc, char *argv[])
{
struct friendList friends[10];

struct friendList *current = (struct friendList *)NULL;

//link each friend to next one
int i = 0;
for(i = 0; i < 3; i++)
{
friends[i].next = &friends[i+1];
}
friends[3].next = NULL;

//assign values to friends we know
friends[0].name = "John";
friends[1].name = "Frank";
friends[2].name = "Alice";
friends[3].name = "Jennifer";

//lets see how easy iterating through this list really is
printf("My friends are:\n");
current = friends; //point to first element
while(current != NULL)
{
printf("%s\n", current->name);
current = current->next; //remember this one?
}

return EXIT_SUCCESS;
}


Linked lists become much more useful when you make them doubly-linked-lists by specifying a previous as well as a next member of each element. This allows you to iterate through the list in both directions and from any point.
In real life link lists are usually used to make it possible to sort them or to add elements to the list at any place, which you cannot easily do with simpler data structures like arrays.

For example, to add your new friend Sarah to the list right behind John, you could do the following:
  current = friends;
struct friendList sarah;
sarah.name = "Sarah";
sarah.next = current->next;
current->next = &sarah;


As an exercise try adding the snippet above to the program and let the same while-loop run again. You will see that without any changes to the loop the output shows Sarah has joined the list and is at the correct position.

No comments: