00001 /* 00002 * $Id: tree234.h 2 2005-06-13 16:47:24Z bogdan_iancu $ 00003 * 00004 * tree234.h: header defining functions in tree234.c. 00005 * 00006 * This file is copyright 1999-2001 Simon Tatham. 00007 * 00008 * Permission is hereby granted, free of charge, to any person 00009 * obtaining a copy of this software and associated documentation 00010 * files (the "Software"), to deal in the Software without 00011 * restriction, including without limitation the rights to use, 00012 * copy, modify, merge, publish, distribute, sublicense, and/or 00013 * sell copies of the Software, and to permit persons to whom the 00014 * Software is furnished to do so, subject to the following 00015 * conditions: 00016 * 00017 * The above copyright notice and this permission notice shall be 00018 * included in all copies or substantial portions of the Software. 00019 * 00020 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 00021 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 00022 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 00023 * NONINFRINGEMENT. IN NO EVENT SHALL SIMON TATHAM BE LIABLE FOR 00024 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 00025 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 00026 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 00027 * SOFTWARE. 00028 * 00029 */ 00030 00031 00032 #ifndef TREE234_H 00033 #define TREE234_H 00034 00035 /* 00036 * This typedef is opaque outside tree234.c itself. 00037 */ 00038 typedef struct tree234_Tag tree234; 00039 00040 typedef int (*cmpfn234)(void *, void *); 00041 00042 /** 00043 * function for deallocation of a element pointer from a node 00044 */ 00045 typedef void (*freefn)(void *); 00046 00047 /* 00048 * Create a 2-3-4 tree. If `cmp' is NULL, the tree is unsorted, and 00049 * lookups by key will fail: you can only look things up by numeric 00050 * index, and you have to use addpos234() and delpos234(). 00051 */ 00052 tree234 *newtree234(cmpfn234 cmp); 00053 00054 /* 00055 * Free a 2-3-4 tree (not including freeing the elements). 00056 */ 00057 void freetree234(tree234 *t); 00058 00059 /* 00060 * Free a 2-3-4 tree (including freeing the elements with 'fn' function). 00061 */ 00062 void free2tree234(tree234 *t, freefn fn); 00063 00064 /* 00065 * Add an element e to a sorted 2-3-4 tree t. Returns e on success, 00066 * or if an existing element compares equal, returns that. 00067 */ 00068 void *add234(tree234 *t, void *e); 00069 00070 /* 00071 * Add an element e to an unsorted 2-3-4 tree t. Returns e on 00072 * success, NULL on failure. (Failure should only occur if the 00073 * index is out of range or the tree is sorted.) 00074 * 00075 * Index range can be from 0 to the tree's current element count, 00076 * inclusive. 00077 */ 00078 void *addpos234(tree234 *t, void *e, int index); 00079 00080 /* 00081 * Look up the element at a given numeric index in a 2-3-4 tree. 00082 * Returns NULL if the index is out of range. 00083 * 00084 * One obvious use for this function is in iterating over the whole 00085 * of a tree (sorted or unsorted): 00086 * 00087 * for (i = 0; (p = index234(tree, i)) != NULL; i++) consume(p); 00088 * 00089 * or 00090 * 00091 * int maxcount = count234(tree); 00092 * for (i = 0; i < maxcount; i++) { 00093 * p = index234(tree, i); 00094 * assert(p != NULL); 00095 * consume(p); 00096 * } 00097 */ 00098 void *index234(tree234 *t, int index); 00099 00100 /* 00101 * Find an element e in a sorted 2-3-4 tree t. Returns NULL if not 00102 * found. e is always passed as the first argument to cmp, so cmp 00103 * can be an asymmetric function if desired. cmp can also be passed 00104 * as NULL, in which case the compare function from the tree proper 00105 * will be used. 00106 * 00107 * Three of these functions are special cases of findrelpos234. The 00108 * non-`pos' variants lack the `index' parameter: if the parameter 00109 * is present and non-NULL, it must point to an integer variable 00110 * which will be filled with the numeric index of the returned 00111 * element. 00112 * 00113 * The non-`rel' variants lack the `relation' parameter. This 00114 * parameter allows you to specify what relation the element you 00115 * provide has to the element you're looking for. This parameter 00116 * can be: 00117 * 00118 * REL234_EQ - find only an element that compares equal to e 00119 * REL234_LT - find the greatest element that compares < e 00120 * REL234_LE - find the greatest element that compares <= e 00121 * REL234_GT - find the smallest element that compares > e 00122 * REL234_GE - find the smallest element that compares >= e 00123 * 00124 * Non-`rel' variants assume REL234_EQ. 00125 * 00126 * If `rel' is REL234_GT or REL234_LT, the `e' parameter may be 00127 * NULL. In this case, REL234_GT will return the smallest element 00128 * in the tree, and REL234_LT will return the greatest. This gives 00129 * an alternative means of iterating over a sorted tree, instead of 00130 * using index234: 00131 * 00132 * // to loop forwards 00133 * for (p = NULL; (p = findrel234(tree, p, NULL, REL234_GT)) != NULL ;) 00134 * consume(p); 00135 * 00136 * // to loop backwards 00137 * for (p = NULL; (p = findrel234(tree, p, NULL, REL234_LT)) != NULL ;) 00138 * consume(p); 00139 */ 00140 enum { 00141 REL234_EQ, REL234_LT, REL234_LE, REL234_GT, REL234_GE 00142 }; 00143 void *find234(tree234 *t, void *e, cmpfn234 cmp); 00144 void *findrel234(tree234 *t, void *e, cmpfn234 cmp, int relation); 00145 void *findpos234(tree234 *t, void *e, cmpfn234 cmp, int *index); 00146 void *findrelpos234(tree234 *t, void *e, cmpfn234 cmp, int relation, 00147 int *index); 00148 00149 /* 00150 * Delete an element e in a 2-3-4 tree. Does not free the element, 00151 * merely removes all links to it from the tree nodes. 00152 * 00153 * delpos234 deletes the element at a particular tree index: it 00154 * works on both sorted and unsorted trees. 00155 * 00156 * del234 deletes the element passed to it, so it only works on 00157 * sorted trees. (It's equivalent to using findpos234 to determine 00158 * the index of an element, and then passing that index to 00159 * delpos234.) 00160 * 00161 * Both functions return a pointer to the element they delete, for 00162 * the user to free or pass on elsewhere or whatever. If the index 00163 * is out of range (delpos234) or the element is already not in the 00164 * tree (del234) then they return NULL. 00165 */ 00166 void *del234(tree234 *t, void *e); 00167 void *delpos234(tree234 *t, int index); 00168 00169 /* 00170 * Return the total element count of a tree234. 00171 */ 00172 int count234(tree234 *t); 00173 00174 #endif /* TREE234_H */
1.5.6