00001 #ifndef UBI_SPLAYTREE_H 00002 #define UBI_SPLAYTREE_H 00003 /* ========================================================================== ** 00004 * ubi_SplayTree.h 00005 * 00006 * Copyright (C) 1993-1998 by Christopher R. Hertel 00007 * 00008 * Email: crh@ubiqx.mn.org 00009 * -------------------------------------------------------------------------- ** 00010 * 00011 * This module implements "splay" trees. Splay trees are binary trees 00012 * that are rearranged (splayed) whenever a node is accessed. The 00013 * splaying process *tends* to make the tree bushier (improves balance), 00014 * and the nodes that are accessed most frequently *tend* to be closer to 00015 * the top. 00016 * 00017 * References: "Self-Adjusting Binary Search Trees", by Daniel Sleator and 00018 * Robert Tarjan. Journal of the Association for Computing 00019 * Machinery Vol 32, No. 3, July 1985 pp. 652-686 00020 * 00021 * See also: http://www.cs.cmu.edu/~sleator/ 00022 * 00023 * -------------------------------------------------------------------------- ** 00024 * 00025 * This library is free software; you can redistribute it and/or 00026 * modify it under the terms of the GNU Library General Public 00027 * License as published by the Free Software Foundation; either 00028 * version 2 of the License, or (at your option) any later version. 00029 * 00030 * This library is distributed in the hope that it will be useful, 00031 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00032 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00033 * Library General Public License for more details. 00034 * 00035 * You should have received a copy of the GNU Library General Public 00036 * License along with this library; if not, write to the Free 00037 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00038 * 00039 * -------------------------------------------------------------------------- ** 00040 * 00041 * $Log: ubi_SplayTree.h,v $ 00042 * Revision 1.1 2004/01/14 20:27:14 dwarren 00043 * XSB Prolog Profiling as command line option -p 00044 * 00045 * Revision 4.5 2000/01/08 23:26:49 crh 00046 * Added ubi_trSplay() macro, which does a type cast for us. 00047 * 00048 * Revision 4.4 1998/06/04 21:29:27 crh 00049 * Upper-cased defined constants (eg UBI_BINTREE_H) in some header files. 00050 * This is more "standard", and is what people expect. Weird, eh? 00051 * 00052 * Revision 4.3 1998/06/03 17:45:05 crh 00053 * Further fiddling with sys_include.h. It's now in ubi_BinTree.h which is 00054 * included by all of the binary tree files. 00055 * 00056 * Also fixed some warnings produced by lint on Irix 6.2, which doesn't seem 00057 * to like syntax like this: 00058 * 00059 * if( (a = b) ) 00060 * 00061 * The fix was to change lines like the above to: 00062 * 00063 * if( 0 != (a=b) ) 00064 * 00065 * Which means the same thing. 00066 * 00067 * Reminder: Some of the ubi_tr* macros in ubi_BinTree.h are redefined in 00068 * ubi_AVLtree.h and ubi_SplayTree.h. This allows easy swapping 00069 * of tree types by simply changing a header. Unfortunately, the 00070 * macro redefinitions in ubi_AVLtree.h and ubi_SplayTree.h will 00071 * conflict if used together. You must either choose a single tree 00072 * type, or use the underlying function calls directly. Compare 00073 * the two header files for more information. 00074 * 00075 * Revision 4.2 1998/06/02 01:29:14 crh 00076 * Changed ubi_null.h to sys_include.h to make it more generic. 00077 * 00078 * Revision 4.1 1998/05/20 04:37:54 crh 00079 * The C file now includes ubi_null.h. See ubi_null.h for more info. 00080 * 00081 * Revision 4.0 1998/03/10 03:40:57 crh 00082 * Minor comment changes. The revision number is now 4.0 to match the 00083 * BinTree and AVLtree modules. 00084 * 00085 * Revision 2.7 1998/01/24 06:37:57 crh 00086 * Added a URL for more information. 00087 * 00088 * Revision 2.6 1997/12/23 04:02:20 crh 00089 * In this version, all constants & macros defined in the header file have 00090 * the ubi_tr prefix. Also cleaned up anything that gcc complained about 00091 * when run with '-pedantic -fsyntax-only -Wall'. 00092 * 00093 * Revision 2.5 1997/07/26 04:15:46 crh 00094 * + Cleaned up a few minor syntax annoyances that gcc discovered for me. 00095 * + Changed ubi_TRUE and ubi_FALSE to ubi_trTRUE and ubi_trFALSE. 00096 * 00097 * Revision 2.4 1997/06/03 05:22:56 crh 00098 * Changed TRUE and FALSE to ubi_TRUE and ubi_FALSE to avoid causing 00099 * problems. 00100 * 00101 * Revision 2.3 1995/10/03 22:19:37 CRH 00102 * Ubisized! 00103 * Also, added the function ubi_sptSplay(). 00104 * 00105 * Revision 2.1 95/03/09 23:55:04 CRH 00106 * Added the ModuleID static string and function. These modules are now 00107 * self-identifying. 00108 * 00109 * Revision 2.0 95/02/27 22:34:55 CRH 00110 * This module was updated to match the interface changes made to the 00111 * ubi_BinTree module. In particular, the interface to the Locate() function 00112 * has changed. See ubi_BinTree for more information on changes and new 00113 * functions. 00114 * 00115 * The revision number was also upped to match ubi_BinTree. 00116 * 00117 * 00118 * Revision 1.0 93/10/15 22:59:36 CRH 00119 * With this revision, I have added a set of #define's that provide a single, 00120 * standard API to all existing tree modules. Until now, each of the three 00121 * existing modules had a different function and typedef prefix, as follows: 00122 * 00123 * Module Prefix 00124 * ubi_BinTree ubi_bt 00125 * ubi_AVLtree ubi_avl 00126 * ubi_SplayTree ubi_spt 00127 * 00128 * To further complicate matters, only those portions of the base module 00129 * (ubi_BinTree) that were superceeded in the new module had the new names. 00130 * For example, if you were using ubi_SplayTree, the locate function was 00131 * called "ubi_sptLocate", but the next and previous functions remained 00132 * "ubi_btNext" and "ubi_btPrev". 00133 * 00134 * This was not too terrible if you were familiar with the modules and knew 00135 * exactly which tree model you wanted to use. If you wanted to be able to 00136 * change modules (for speed comparisons, etc), things could get messy very 00137 * quickly. 00138 * 00139 * So, I have added a set of defined names that get redefined in any of the 00140 * descendant modules. To use this standardized interface in your code, 00141 * simply replace all occurances of "ubi_bt", "ubi_avl", and "ubi_spt" with 00142 * "ubi_tr". The "ubi_tr" names will resolve to the correct function or 00143 * datatype names for the module that you are using. Just remember to 00144 * include the header for that module in your program file. Because these 00145 * names are handled by the preprocessor, there is no added run-time 00146 * overhead. 00147 * 00148 * Note that the original names do still exist, and can be used if you wish 00149 * to write code directly to a specific module. This should probably only be 00150 * done if you are planning to implement a new descendant type, such as 00151 * red/black trees. CRH 00152 * 00153 * Revision 0.0 93/04/21 23:07:13 CRH 00154 * Initial version, written by Christopher R. Hertel. 00155 * This module implements Splay Trees using the ubi_BinTree module as a basis. 00156 * 00157 * ========================================================================== ** 00158 */ 00159 00160 #include "ubi_BinTree.h" /* Base binary tree functions, types, etc. */ 00161 00162 /* ========================================================================== ** 00163 * Function prototypes... 00164 */ 00165 00166 ubi_trBool ubi_sptInsert( ubi_btRootPtr RootPtr, 00167 ubi_btNodePtr NewNode, 00168 ubi_btItemPtr ItemPtr, 00169 ubi_btNodePtr *OldNode ); 00170 /* ------------------------------------------------------------------------ ** 00171 * This function uses a non-recursive algorithm to add a new element to the 00172 * splay tree. 00173 * 00174 * Input: RootPtr - a pointer to the ubi_btRoot structure that indicates 00175 * the root of the tree to which NewNode is to be added. 00176 * NewNode - a pointer to an ubi_btNode structure that is NOT 00177 * part of any tree. 00178 * ItemPtr - A pointer to the sort key that is stored within 00179 * *NewNode. ItemPtr MUST point to information stored 00180 * in *NewNode or an EXACT DUPLICATE. The key data 00181 * indicated by ItemPtr is used to place the new node 00182 * into the tree. 00183 * OldNode - a pointer to an ubi_btNodePtr. When searching 00184 * the tree, a duplicate node may be found. If 00185 * duplicates are allowed, then the new node will 00186 * be simply placed into the tree. If duplicates 00187 * are not allowed, however, then one of two things 00188 * may happen. 00189 * 1) if overwritting *is not* allowed, this 00190 * function will return FALSE (indicating that 00191 * the new node could not be inserted), and 00192 * *OldNode will point to the duplicate that is 00193 * still in the tree. 00194 * 2) if overwritting *is* allowed, then this 00195 * function will swap **OldNode for *NewNode. 00196 * In this case, *OldNode will point to the node 00197 * that was removed (thus allowing you to free 00198 * the node). 00199 * ** If you are using overwrite mode, ALWAYS ** 00200 * ** check the return value of this parameter! ** 00201 * Note: You may pass NULL in this parameter, the 00202 * function knows how to cope. If you do this, 00203 * however, there will be no way to return a 00204 * pointer to an old (ie. replaced) node (which is 00205 * a problem if you are using overwrite mode). 00206 * 00207 * Output: a boolean value indicating success or failure. The function 00208 * will return FALSE if the node could not be added to the tree. 00209 * Such failure will only occur if duplicates are not allowed, 00210 * nodes cannot be overwritten, AND a duplicate key was found 00211 * within the tree. 00212 * ------------------------------------------------------------------------ ** 00213 */ 00214 00215 ubi_btNodePtr ubi_sptRemove( ubi_btRootPtr RootPtr, ubi_btNodePtr DeadNode ); 00216 /* ------------------------------------------------------------------------ ** 00217 * This function removes the indicated node from the tree. 00218 * 00219 * Input: RootPtr - A pointer to the header of the tree that contains 00220 * the node to be removed. 00221 * DeadNode - A pointer to the node that will be removed. 00222 * 00223 * Output: This function returns a pointer to the node that was removed 00224 * from the tree (ie. the same as DeadNode). 00225 * 00226 * Note: The node MUST be in the tree indicated by RootPtr. If not, 00227 * strange and evil things will happen to your trees. 00228 * ------------------------------------------------------------------------ ** 00229 */ 00230 00231 ubi_btNodePtr ubi_sptLocate( ubi_btRootPtr RootPtr, 00232 ubi_btItemPtr FindMe, 00233 ubi_trCompOps CompOp ); 00234 /* ------------------------------------------------------------------------ ** 00235 * The purpose of ubi_btLocate() is to find a node or set of nodes given 00236 * a target value and a "comparison operator". The Locate() function is 00237 * more flexible and (in the case of trees that may contain dupicate keys) 00238 * more precise than the ubi_btFind() function. The latter is faster, 00239 * but it only searches for exact matches and, if the tree contains 00240 * duplicates, Find() may return a pointer to any one of the duplicate- 00241 * keyed records. 00242 * 00243 * Input: 00244 * RootPtr - A pointer to the header of the tree to be searched. 00245 * FindMe - An ubi_btItemPtr that indicates the key for which to 00246 * search. 00247 * CompOp - One of the following: 00248 * CompOp Return a pointer to the node with 00249 * ------ --------------------------------- 00250 * ubi_trLT - the last key value that is less 00251 * than FindMe. 00252 * ubi_trLE - the first key matching FindMe, or 00253 * the last key that is less than 00254 * FindMe. 00255 * ubi_trEQ - the first key matching FindMe. 00256 * ubi_trGE - the first key matching FindMe, or the 00257 * first key greater than FindMe. 00258 * ubi_trGT - the first key greater than FindMe. 00259 * Output: 00260 * A pointer to the node matching the criteria listed above under 00261 * CompOp, or NULL if no node matched the criteria. 00262 * 00263 * Notes: 00264 * In the case of trees with duplicate keys, Locate() will behave as 00265 * follows: 00266 * 00267 * Find: 3 Find: 3 00268 * Keys: 1 2 2 2 3 3 3 3 3 4 4 Keys: 1 1 2 2 2 4 4 5 5 5 6 00269 * ^ ^ ^ ^ ^ 00270 * LT EQ GT LE GE 00271 * 00272 * That is, when returning a pointer to a node with a key that is LESS 00273 * THAN the target key (FindMe), Locate() will return a pointer to the 00274 * LAST matching node. 00275 * When returning a pointer to a node with a key that is GREATER 00276 * THAN the target key (FindMe), Locate() will return a pointer to the 00277 * FIRST matching node. 00278 * 00279 * See Also: ubi_btFind(), ubi_btFirstOf(), ubi_btLastOf(). 00280 * ------------------------------------------------------------------------ ** 00281 */ 00282 00283 ubi_btNodePtr ubi_sptFind( ubi_btRootPtr RootPtr, 00284 ubi_btItemPtr FindMe ); 00285 /* ------------------------------------------------------------------------ ** 00286 * This function performs a non-recursive search of a tree for any node 00287 * matching a specific key. 00288 * 00289 * Input: 00290 * RootPtr - a pointer to the header of the tree to be searched. 00291 * FindMe - a pointer to the key value for which to search. 00292 * 00293 * Output: 00294 * A pointer to a node with a key that matches the key indicated by 00295 * FindMe, or NULL if no such node was found. 00296 * 00297 * Note: In a tree that allows duplicates, the pointer returned *might 00298 * not* point to the (sequentially) first occurance of the 00299 * desired key. In such a tree, it may be more useful to use 00300 * ubi_sptLocate(). 00301 * ------------------------------------------------------------------------ ** 00302 */ 00303 00304 void ubi_sptSplay( ubi_btRootPtr RootPtr, 00305 ubi_btNodePtr SplayMe ); 00306 /* ------------------------------------------------------------------------ ** 00307 * This function allows you to splay the tree at a given node, thus moving 00308 * the node to the top of the tree. 00309 * 00310 * Input: 00311 * RootPtr - a pointer to the header of the tree to be splayed. 00312 * SplayMe - a pointer to a node within the tree. This will become 00313 * the new root node. 00314 * Output: None. 00315 * 00316 * Notes: This is an uncharacteristic function for this group of modules 00317 * in that it provides access to the internal balancing routines, 00318 * which would normally be hidden. 00319 * Splaying the tree will not damage it (assuming that I've done 00320 * *my* job), but there is overhead involved. I don't recommend 00321 * that you use this function unless you understand the underlying 00322 * Splay Tree principles involved. 00323 * ------------------------------------------------------------------------ ** 00324 */ 00325 00326 int ubi_sptModuleID( int size, char *list[] ); 00327 /* ------------------------------------------------------------------------ ** 00328 * Returns a set of strings that identify the module. 00329 * 00330 * Input: size - The number of elements in the array <list>. 00331 * list - An array of pointers of type (char *). This array 00332 * should, initially, be empty. This function will fill 00333 * in the array with pointers to strings. 00334 * Output: The number of elements of <list> that were used. If this value 00335 * is less than <size>, the values of the remaining elements are 00336 * not guaranteed. 00337 * 00338 * Notes: Please keep in mind that the pointers returned indicate strings 00339 * stored in static memory. Don't free() them, don't write over 00340 * them, etc. Just read them. 00341 * ------------------------------------------------------------------------ ** 00342 */ 00343 00344 /* -------------------------------------------------------------------------- ** 00345 * Masquarade... 00346 * 00347 * This set of defines allows you to write programs that will use any of the 00348 * implemented binary tree modules (currently BinTree, AVLtree, and SplayTree). 00349 * Instead of using ubi_bt..., use ubi_tr..., and select the tree type by 00350 * including the appropriate module header. 00351 */ 00352 00353 #undef ubi_trInsert 00354 #undef ubi_trRemove 00355 #undef ubi_trLocate 00356 #undef ubi_trFind 00357 #undef ubi_trModuleID 00358 00359 #define ubi_trInsert( Rp, Nn, Ip, On ) \ 00360 ubi_sptInsert( (ubi_btRootPtr)(Rp), (ubi_btNodePtr)(Nn), \ 00361 (ubi_btItemPtr)(Ip), (ubi_btNodePtr *)(On) ) 00362 00363 #define ubi_trRemove( Rp, Dn ) \ 00364 ubi_sptRemove( (ubi_btRootPtr)(Rp), (ubi_btNodePtr)(Dn) ) 00365 00366 #define ubi_trLocate( Rp, Ip, Op ) \ 00367 ubi_sptLocate( (ubi_btRootPtr)(Rp), \ 00368 (ubi_btItemPtr)(Ip), \ 00369 (ubi_trCompOps)(Op) ) 00370 00371 #define ubi_trFind( Rp, Ip ) \ 00372 ubi_sptFind( (ubi_btRootPtr)(Rp), (ubi_btItemPtr)(Ip) ) 00373 00374 #define ubi_trSplay( Rp, Sm ) \ 00375 ubi_sptSplay( (ubi_btRootPtr)(Rp), (ubi_btNodePtr)(Sm) ) 00376 00377 #define ubi_trModuleID( s, l ) ubi_sptModuleID( s, l ) 00378 00379 /* ================================ The End ================================= */ 00380 #endif /* UBI_SPLAYTREE_H */