linklist.h

Go to the documentation of this file.
00001 /* LinkList.H -- ANSI C Linked List Container Type
00002                  Handles Lists, Queues, Stacks, Splay Trees, 
00003        and custom list types via one consistant interface.
00004 
00005          - Written by Jeff Hay, jrhay@lanl.gov
00006            - If you find errors in this library, please let me know!
00007 
00008    What It Does:
00009          - Creates, maintains, and destroys any type of linked memory structure
00010            (singly/doubly linked lists, queues, stacks, etc) effeciently and
00011            without memory leaks.
00012    - Any user-specified data may be held within structure nodes.
00013    - Allows user-definable memory allocation and deallocation routines
00014            to be used in place of standard malloc() and free() calls.
00015    - Any number and types of linked memory structures may be created
00016            (subject only to memory limitations)
00017    - "Should be" portable to any ANSI C compilent platform
00018 
00019    Stuff To Do Yet:
00020          - Add functionallity to be able to interrupt list maintence routines
00021            at any point and still maintain list continuity (for multi-processor
00022            shared memory environments)
00023 
00024   The object file compiled from this library is around 5K depending on 
00025   operating platform.
00026 
00027 */
00028 #ifndef __c_LINKLIST__
00029 #define __c_LINKLIST__
00030 
00031 /* 
00032    NOTE:  All functions assume the list data structures are UNTOUCHED expect
00033           by functions in this library.  Bad things could happen if you muck 
00034     with them at all.  (unless you know what you are doing.... ;)
00035 
00036   This library has been through several incarnations, each one adding features
00037   while maintaining compatibility with the previous versions.  The result is a 
00038   confusing number of functions.  For new programs, the only functions you need
00039   are:
00040           List Creation     - NewListAlloc(), AddNode()
00041     List Destruction  - FreeList(), DelNode()
00042     List Transversal  - NextNode(), PrevNode(), IndexNode()
00043     List Manipulation - GetNode(), GetNodeData()
00044 
00045   All other functions are either internal-use functions or obsolete definitions
00046   to maintain source compatiblity for programs written to older versions of 
00047   this  library.
00048 
00049   Note also that if using the library to maintain binary search trees, the
00050   List Transversal functions should not normally be used.
00051    
00052   See the last section of this header file for extended documentation on all 
00053   functions.
00054 */
00055 
00056 /* Will use the DALLOC library if "dalloc.h" is included on the compiler
00057    command line */
00058 
00059 /* Uncomment the following line to compile an executable from LinkList.C that
00060    will demonstrate and test the functions contained in this library. (or 
00061    define LINKLIST_TEST on the compiler command line ("make linklist") */
00062 /* #define LINKLIST_TEST 1  */
00063 
00064 /* -------
00065    Include files used by this library
00066 ------- */
00067 #include <stdio.h>
00068 #include <stdlib.h>
00069 
00070 /* --------
00071    List Flags and Parameters
00072 -------- */
00073 
00074 /* List Parameters */
00075 #define LISTADDCURR   0x300  /* Add New Node At Current Record In List */
00076 #define LISTADDHEAD   0x100  /* Add New Nodes At Head Of List */
00077 #define LISTADDTAIL   0x200  /* Add New Nodes At Tail Of List */
00078 #define LISTADDSPLAY  0x400  /* Add New Nodes As A Splay Tree */
00079 #define LISTDELCURR   0x030  /* Delete Nodes At Current Record */
00080 #define LISTDELHEAD   0x010  /* Delete Nodes At Head Of List */
00081 #define LISTDELTAIL   0x020  /* Delete Nodes At Tail Of List */
00082 #define LISTDELSPLAY  0x040  /* Delete Nodes As A Splay Tree */
00083 #define LISTREADCURR  0x003  /* Read List At Current Node */
00084 #define LISTREADHEAD  0x001  /* Read Head Of List */
00085 #define LISTREADTAIL  0x002  /* Read Tail Of List */
00086 
00087 #define LISTDELREAD   0x1000 /* Delete Node On Reading */
00088 #define LISTCIRCULAR  0x2000 /* Circular List - Head->Next=Tail, etc */
00089 #define LISTBTREE     0x4000 /* List is actually a binary tree */
00090 
00091 /* Masks of List Parameters */
00092 #define LISTADDMASK  0xF00  /* Add New Node Method */
00093 #define LISTDELMASK  0x0F0  /* Delete Node Method */
00094 #define LISTREADMASK 0x00F  /* Read Node Method */
00095 #define LISTFLAGMASK 0xF000 /* Operation Flags */
00096 
00097 /* Common Data Structure Types */
00098 #define LIST (LISTADDCURR | LISTREADCURR | LISTDELCURR) 
00099 #define FIFO (LISTADDTAIL | LISTREADHEAD | LISTDELHEAD)
00100 #define LIFO (LISTADDHEAD | LISTREADHEAD | LISTDELHEAD)
00101 #define QUEUE (FIFO | LISTDELREAD)
00102 #define STACK (LIFO | LISTDELREAD)
00103 #define CIRCULAR_QUEUE (QUEUE | LISTCIRCULAR)
00104 #define STREE (LISTBTREE | LISTADDSPLAY | LISTDELSPLAY | LISTREADCURR)
00105 
00106 /* --------
00107    Possible return values of functions in this library 
00108 -------- */
00109 #define LLIST_NOERROR 0    /* No problem! */
00110 #define LLIST_NULL    1    /* Bad value passed to function */
00111 #define LLIST_ERROR  -1    /* Misc. program/library error.  Serious trouble! */
00112 
00113 #define LLIST_OK LLIST_NOERROR   /* duplicate definitions for compatibility */
00114 #define LLIST_BADVALUE LLIST_NULL
00115 
00116 /* --------
00117    List data structures
00118 -------- */
00119 
00120 typedef void (*ListFreeFunc)(void *); 
00121 /* Function to release memory stored within a list (free() syntax) */
00122 
00123 typedef void *(* ListAlloc)(size_t size);
00124 /* Memory allocation procedure to use for this list (malloc() syntax) */
00125 
00126 typedef int (* NodeCompareFunc)(void *, void *);
00127 /* Function used to compare nodes for list sorting.  The two passed pointers
00128    are two data elements from nodes of a list.  CompareFunc must return:
00129                 1 iff First Node > Second Node
00130                 0 iff First Node = Second Node
00131                -1 iff First Node < Second Node  
00132    Results are undefined if one or both pointers are NULL. (note that this
00133    definition is compatible with strcmp() and related functions) */ 
00134 
00135 typedef int (* ListDumpFunc)(void *);
00136 /* Function to dump the data of a node to the screen */
00137 
00138 typedef struct ListNode* listnodePtr;
00139 typedef struct ListNode
00140 {  
00141   void        *Data;  /* Data stored at this node (user-defined) */
00142   listnodePtr Next,   /* Next Node in List, Right Child in Binary Tree */
00143               Prev;   /* Previous Node in List, Left Child in Binary Tree */
00144 } listnode;
00145 
00146 typedef struct LList* listPtr;
00147 typedef struct LList
00148 {  
00149   listnodePtr  Current,  /* Last Accessed Node */ 
00150                Head,     /* Head of List, Root of Binary Tree */ 
00151                Tail;     /* Tail of List */
00152   int          Size,     /* Number of nodes in List or Binary Tree */ 
00153                Flags;    /* Flags associated with List/Tree */
00154   ListAlloc    memalloc; /* malloc()-type procedure to use */
00155   ListFreeFunc memfree;  /* free()-type procedure to use */
00156   NodeCompareFunc compare; /* Function to use to compare nodes */
00157 } llist;
00158 
00159 /* -------
00160    Make sure we have DALLOC (or similarly-named macros)
00161 -------- */
00162 
00163 #ifndef DMALLOC
00164 #define DMALLOC malloc
00165 #endif
00166 #ifndef DFREE
00167 #define DFREE dfree
00168 #endif
00169 #ifndef DCOUNT
00170 #define DCOUNT dcount
00171 #endif
00172 
00173 /* --------
00174   Function Prototypes
00175 -------- */
00176 
00177 listPtr NewListAlloc(int ListType, ListAlloc Lalloc, ListFreeFunc Lfree,
00178          NodeCompareFunc Cfunc);
00179 /* Create a brand new list structure.  The structrue is defined by
00180    ListType, which is a logical OR of the List Parameters defined above.
00181    Use the specified allocation and free function to allocate dynamic
00182    memory to the list.  If "alloc" or "free" are NULL, default to
00183    malloc() and free() (respectively) from stdlib.  If "Cfunc" is NULL, don't
00184    do comparisons.
00185 
00186    Returns
00187         Pointer to a new list
00188         NULL on error (Lalloc() procedure failed) */
00189 
00190 #define NewList(Type) NewListAlloc(Type, NULL, NULL, NULL)
00191 /* Macro definition of: listPtr NewList(int ListType); 
00192    for compatibility with previous versions of library */
00193 
00194 listnodePtr NewListNode(listPtr List, void *Data);
00195 /* Creates a new node for the specified list.  Memory is allocated with
00196    the list alloc procedure.  Data is a pointer to any kind of data or may
00197    be NULL.  If List is NULL, node is created using malloc().
00198    Returns 
00199         Pointer to the new node
00200         NULL on error (alloc failed) */
00201 
00202 #define NewNode(Data) NewListNode(NULL, Data)
00203 /* Macro definition of: listnodePtr NewNode(void *Data);
00204    for compatibility with previous versions of library */
00205 
00206 void *GetNode(listPtr List);
00207 /* Reads the next node in the list (as specified at list creation with one of 
00208    the LISTREAD* properties).  If list has unknown LISTREAD* property, returns
00209    as LISTREADCURR.  If LISTDELREAD is a property of the list, the
00210    node is automatically deleted (note that the node DATA is *not* free()'d).  
00211 
00212    Returns
00213         Pointer to the node data
00214         NULL if List is NULL or empty (or list read property is unknown) */
00215 
00216 void *FindNode(listPtr List, void *Data);
00217 /* Finds a node in the list for which the list compare function specified at
00218    list creation returns 0 when compared with "Data".  Sets List->Current to
00219    the found node, and returns found node's data.
00220 
00221    Returns
00222        Pointer to the node data
00223        NULL if list empty
00224             if no list compare function
00225             if no node matching data was found in list
00226 */
00227 
00228 void *BTFind(listPtr List, void *Data);
00229 /*  Performs "FindNode" operation when list is a binary tree; called 
00230     automatically by FindNode() when list has LISTBTREE property set.  */
00231 
00232 void *GetNodeData(listnodePtr Node);
00233 /* Returns the data contained in the specified node, or NULL if Node is empty*/
00234 
00235 int AddNode(listPtr List, listnodePtr Node);
00236 /* Adds a node to the list in the location specified at list creation by one of
00237    the LISTADD* properties.  If the LISTADD property is unknown for any reason
00238    (program error), the node is added at the current list position.  Node must
00239    be created by NewListNode.  Current list pointer is set to the newly added
00240    node.  
00241    Returns
00242         LLIST_NOERROR on success
00243   LLIST_NULL if either List or Node are NULL 
00244   LLIST_ERROR on undefined program error */
00245 
00246 int InsertList(listPtr List, listnodePtr Node);
00247 int HeadList(listPtr List, listnodePtr Node);
00248 int TailList(listPtr List, listnodePtr Node);
00249 int SplayInsertList(listPtr List, listnodePtr Node);
00250 /* These functions add the specified node to the specified list at the either 
00251    the current position, the head of the list, the tail of the list, ,or in a
00252    splay pattern, respectively.  All assume the node has been init'd
00253    by NewNode() and all set List->Current to the newly added node.
00254 
00255    These functions should not normally be called directly by user programs
00256    (AddNode() will call the approrpiate function for the list)
00257 
00258    All return
00259         LLIST_NOERROR on success
00260   LLIST_NULL if either List or Node are NULL */
00261 
00262 int DelNode(listPtr List);
00263 /* Deletes a node from the list. The node deleted is specified at list creation
00264    by one of the LISTDEL* properties. If the LISTDEL property is unknown for
00265    any reson, the "current" node is deleted.  Current list position is set to 
00266    the next logical node in the list (or NULL).  Note: Note DATA is *not*
00267    deleted.
00268 
00269    Returns
00270         LLIST_NOERROR on success
00271   LLIST_NULL if List is NULL
00272   LLIST_ERROR on undefined program error */
00273 
00274 int RemoveList(listPtr List);
00275 int DelHeadList(listPtr List);
00276 int DelTailList(listPtr List);
00277 /* These functions delete the node at either the current list position,
00278    the head of the list, the tail of the list, or as a splay pattern,
00279    respectively.  All set List->Current to the next node in the list 
00280    (Node->Next).
00281 
00282    These functions should not normally be called directly by user programs
00283    (DelNode() will call the approrpiate function for the list)
00284 
00285    All Return
00286         LLIST_NOERROR on success
00287   LLIST_NULL if List is NULL */
00288 
00289 void *NextNode(listPtr List);
00290 /* Step to the next logical node in the list.  For lists with LISTBTREE set, 
00291    steps to the right child of the current node.
00292 
00293    Returns
00294         NULL if List or next node is empty
00295   Pointer to the next node's data on success */
00296 
00297 void *PrevNode(listPtr List);
00298 /* Step to the previous logical node in the list. For lists with LISTBTREE set,
00299    steps to the left child of the current node.
00300 
00301    Returns
00302         NULL if List or next node is empty
00303   Pointer to the next node's data on success */
00304 
00305 void *IndexNode(listPtr List, int Index);
00306 /* Step to the logical node numbed "Index" in the List.  The head of
00307    the list is index "1"; the tail is index "List->Size".  If LISTBTREE is set,
00308    this function always returns NULL (Indexing makes no sense).
00309 
00310    Returns
00311         NULL if List or indexed node is empty
00312        if Index > size of list
00313   Pointer to the index node's data on success */
00314 
00315 int FreeList(listPtr List, ListFreeFunc DataFree);
00316 /* Deletes entire list structure and frees all memory.  List is undefined
00317    after this call.  "DataFree" is an optional function used to free the
00318    memory allocated for each node's data (ie, if the data is a dynamic 
00319    structure, etc); it may be NULL.  It will *not* be called for empty
00320    nodes (node->data == NULL).  If this function returns with anything 
00321    other then LLIST_NOERROR, an error was encountered deleting a node from
00322    the list.  List is in undefined state. */
00323 
00324 void SwapList(listPtr List);
00325 /* Swaps the current node in the list with the next node in the list.  No
00326    function if current node is tail of list.  */
00327 
00328 void SortList(listPtr List);
00329 /* Preforms a slow sort on the list.  Sort is handled in-place.  Current node
00330    is head of list after sort.  Does not  attempt to sort lists with LISTBTREE
00331    property set.
00332 */
00333 
00334 void *SplayList(listPtr List, void *Data);
00335 /* Performs a splay operation on the list.  The list is assumed to be a splay
00336    tree.  Finds the node in the tree that matches "Data" and moves that node
00337    (or the closest node less then data) to the root of the tree, preserving the
00338    inorder transversal of the tree.
00339 
00340    Returns
00341            Pointer to node data if found
00342            NULL if List is NULL
00343           if "Data" not found in Tree */         
00344 
00345 int IntCompare(int *First, int* Second);
00346 int StringCompare(char *First, char* Second);
00347 int DoubleCompare(double *First, double* Second);
00348 /* These are suitable NodeCompareFunc functions for three common types of
00349    nodes.  Provided just to make life a little easier... */
00350 
00351 int DumpList(listPtr List, ListDumpFunc DataDump);
00352 /* Print List data using the DataDump function for Node Data Elements */
00353 
00354 #ifdef LINKLIST_TEST
00355 
00356 int PrintList(listPtr List, char *DataFmt);
00357 /*  Display the contents of a list.  Provided mainly as an example
00358    of how to transverse list if needed.  Written for an old version of
00359    this library and never updated. */
00360 
00361 int PrintTree(listPtr List, char *DataFmt);
00362 /*  Prints the contents and structure of a Tree using DataFmt as the printf() 
00363     format for Node Data Elements. Called by PrintList as appropriate. */
00364 
00365 #endif
00366 
00367 #endif  /* __c_LINKLIST__ */
00368 
00369 
00370 
00371 
00372