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