LL.h : Linked Lists (Doubly-Linked Lists)

Creating a list

To create a list, do the following:

LinkedList *list;
list = LL_new();
if(!list) handle_an_error();

The list can hold any type of data. You will need to typecast your datatype to a "void *", though. So, to add something to the list, the following would be a good way to start:

typedef struct my_data {
  char string[16];
  int number;
} my_data;

my_data *thingie;

for(something to something else) {
  thingie = malloc(sizeof(my_data));
  LL_AddNode(list, (void *)thingie);  // typecast it to a "void *"
}

For errors, the general convention is that "0" means success, and a negative number means failure. Check LL.c to be sure, though.

Changing data

To change the data, try this:

thingie = (my_data *)LL_Get(list);  // typecast it back to "my_data"
thingie->number = another_number;

You don't need to "Put" the data back, but it doesn't hurt anything.

LL_Put(list, (void *)thingie);

However, if you want to point the node's data somewhere else, you'll need to get the current data first, keep track of it, then set the data to a new location:

my_data * old_thingie, new_thingie;

old_thingie = (my_data *)LL_Get(list);
LL_Put(list, (void *)new_thingie);

// Now, do something with old_thingie.  (maybe, free it?)

Or, you could just delete the node entirely and then add a new one:

my_data * thingie;

thingie = (my_data *)LL_DeleteNode(list);
free(thingie);

thingie->number = 666;

LL_InsertNode(list, (void *)thingie);

Iterations throught the list

To iterate on each list item, try this:

LL_Rewind(list);
do {
  my_data = (my_data *)LL_Get(list);
  /* ... do something to it ... */
} while(LL_Next(list) == 0);

Using the list as a stack or a queue

You can also treat the list like a stack, or a queue. Just use the following functions:

LL_Push()      // Regular stack stuff: add, remove, peek, rotate
LL_Pop()
LL_Top()
LL_Roll()

LL_Shift()     // Other end of the stack (like in perl)
LL_Unshift()
LL_Look()
LL_UnRoll()

LL_Enqueue()   // Standard queue operations
LL_Dequeue()

There are also other goodies, like sorting and searching.

Future

Array-like operations will come later, to allow numerical indexing:

LL_nGet(list, 3);
LL_nSwap(list, 6, 13);
LL_nPut(list, -4, data);   // Puts item at 4th place from the end..

More ideas for later:

LL_MoveNode(list, amount);  // Slides a node to another spot in the list
-- LL_MoveNode(list, -1); // moves a node back one toward the head

That's about it, for now... Be sure to free the list when you're done!

See LL.c for more detailed descriptions of these functions.