utlist: linked list macros for C structures =========================================== Troy D. Hanson v1.9.5, November 2011 include::sflogo.txt[] include::topnav_utlist.txt[] Introduction ------------ include::toc.txt[] A set of general-purpose 'linked list' macros for C structures are included with uthash in `utlist.h`. To use these macros in your own C program, just copy `utlist.h` into your source directory and use it in your programs. #include "utlist.h" These macros support the basic linked list operations: adding and deleting elements, sorting them and iterating over them. Download ~~~~~~~~ To download the `utlist.h` header file, follow the link on the http://uthash.sourceforge.net[uthash home page]. BSD licensed ~~~~~~~~~~~~ This software is made available under the link:license.html[revised BSD license]. It is free and open source. Platforms ~~~~~~~~~ The 'utlist' macros have been tested on: * Linux, * Mac OS X, and * Windows, using Visual Studio 2008, Visual Studio 2010, or Cygwin/MinGW. Using utlist ------------ Types of lists ~~~~~~~~~~~~~~ Three types of linked lists are supported: - *singly-linked* lists, - *doubly-linked* lists, and - *circular, doubly-linked* lists Efficiency ^^^^^^^^^^ For all types of lists, prepending elements and deleting elements are constant-time operations. Appending to a singly-linked list is an 'O(n)' operation but appending to a doubly-linked list is constant time using these macros. (This is because, in the utlist implementation of the doubly-linked list, the head element's `prev` member points back to the list tail, even when the list is non-circular). Sorting is an 'O(n log(n))' operation. Iteration and searching are `O(n)` for all list types. List elements ~~~~~~~~~~~~~ You can use any structure with these macros, as long as the structure contains a `next` pointer. If you want to make a doubly-linked list, the element also needs to have a `prev` pointer. typedef struct element { char *name; struct element *prev; /* needed for a doubly-linked list only */ struct element *next; /* needed for singly- or doubly-linked lists */ } element; You can name your structure anything. In the example above it is called `element`. Within a particular list, all elements must be of the same type. List head ~~~~~~~~~ The list head is simply a pointer to your element structure. You can name it anything. *It must be initialized to `NULL`*. element *head = NULL; List operations ~~~~~~~~~~~~~~~ The lists support inserting or deleting elements, sorting the elements and iterating over them. [width="100%",cols="10 #include #include #include "utlist.h" #define BUFLEN 20 typedef struct el { char bname[BUFLEN]; struct el *next, *prev; } el; int namecmp(el *a, el *b) { return strcmp(a->bname,b->bname); } el *head = NULL; /* important- initialize to NULL! */ int main(int argc, char *argv[]) { el *name, *elt, *tmp, etmp; char linebuf[BUFLEN]; FILE *file; if ( (file = fopen( "test11.dat", "r" )) == NULL ) { perror("can't open: "); exit(-1); } while (fgets(linebuf,BUFLEN,file) != NULL) { if ( (name = (el*)malloc(sizeof(el))) == NULL) exit(-1); strncpy(name->bname,linebuf,BUFLEN); DL_APPEND(head, name); } DL_SORT(head, namecmp); DL_FOREACH(head,elt) printf("%s", elt->bname); memcpy(&etmp.bname, "WES\n", 5); DL_SEARCH(head,elt,&etmp,namecmp); if (elt) printf("found %s\n", elt->bname); /* now delete each element, use the safe iterator */ DL_FOREACH_SAFE(head,elt,tmp) { DL_DELETE(head,elt); } fclose(file); return 0; } -------------------------------------------------------------------------------- // vim: set nowrap syntax=asciidoc: