MISR Toolkit  1.5.1
tbbt.h
Go to the documentation of this file.
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2  * Copyright by The HDF Group. *
3  * Copyright by the Board of Trustees of the University of Illinois. *
4  * All rights reserved. *
5  * *
6  * This file is part of HDF. The full HDF copyright notice, including *
7  * terms governing use, modification, and redistribution, is contained in *
8  * the files COPYING and Copyright.html. COPYING can be found at the root *
9  * of the source code distribution tree; Copyright.html can be found at *
10  * http://hdfgroup.org/products/hdf4/doc/Copyright.html. If you do not have *
11  * access to either file, you may request a copy from help@hdfgroup.org. *
12  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
13 
14 /* $Id: tbbt.h 5444 2010-08-25 16:40:05Z byrn $ */
15 
16 /* "tbbt.h" -- Data types/routines for threaded, balanced, binary trees. */
17 /* Extended from Knuth 6.2.3, Algorithm A */
18 
19 #ifndef TBBT_H
20 #define TBBT_H
21 
22 #include "H4api_adpt.h"
23 
24 #ifdef lint /* lint always complains but may complain more if... */
25 # define TBBT_INTERNALS /* TBBT_INTERNALS not always defined */
26 #endif /* lint */
27 
28 typedef struct tbbt_node TBBT_NODE;
29 
30 /* Threaded node structure */
31 struct tbbt_node
32  {
33  VOIDP data; /* Pointer to user data to be associated with node */
34  VOIDP key; /* Field to sort nodes on */
35 
36 #ifdef TBBT_INTERNALS
37 # define PARENT 0
38 # define LEFT 1
39 # define RIGHT 2
40  TBBT_NODE *link[3]; /* Pointers to parent, left child, and right child */
41 # define Parent link[PARENT]
42 # define Lchild link[LEFT]
43 # define Rchild link[RIGHT]
44 # define TBBT_FLAG unsigned long
45 # define TBBT_LEAF unsigned long
46  TBBT_FLAG flags; /* Combination of the following bit fields: */
47 # define TBBT_HEAVY(s) s /* If the `s' sub-tree is deeper than the other */
48 # define TBBT_DOUBLE 4 /* If "heavy" sub-tree is two levels deeper */
49 # define TBBT_INTERN 8 /* If node is internal (has two children) */
50 # define TBBT_UNBAL ( TBBT_HEAVY(LEFT) | TBBT_HEAVY(RIGHT) )
51 # define TBBT_FLAGS ( TBBT_UNBAL | TBBT_INTERN | TBBT_DOUBLE )
52 # define TBBT_CHILD(s) ( TBBT_INTERN | TBBT_HEAVY(s) )
53  TBBT_LEAF lcnt; /* count of left children */
54  TBBT_LEAF rcnt; /* count of right children */
55 # define LeftCnt(node) ( (node)->lcnt ) /* Left descendants */
56 # define RightCnt(node) ( (node)->rcnt ) /* Left descendants */
57 #if defined macintosh || defined MAC || defined SYMANTEC_C /* Macro substitution limit */
58 # define Cnt(node,s) ( 1==(s) ? LeftCnt(node) : RightCnt(node) )
59 #else /* !macintosh */
60 # define Cnt(node,s) ( LEFT==(s) ? LeftCnt(node) : RightCnt(node) )
61 #endif /* !macintosh */
62 # define HasChild(n,s) ( Cnt(n,s)>0 )
63 # define Heavy(n,s) ( (s) & (LeftCnt(n)>RightCnt(n) ? LEFT : \
64  LeftCnt(n)==RightCnt(n) ? 0 : RIGHT))
65 # define Intern(n) ( LeftCnt(n) && RightCnt(n) )
66 # define UnBal(n) ( LeftCnt(n)>RightCnt(n) ? LEFT : \
67  LeftCnt(n)==RightCnt(n) ? 0 : RIGHT)
68 # define Double(n) ( TBBT_DOUBLE & (n)->flags )
69 # define Other(side) ( LEFT + RIGHT - (side) )
70 # define Delta(n,s) ( ( Heavy(n,s) ? 1 : -1 ) \
71  * ( Double(n) ? 2 : UnBal(n) ? 1 : 0 ) )
72 # define SetFlags(n,s,b,i) ( ( -2<(b) && (b)<2 ? 0 : TBBT_DOUBLE ) \
73  | ( 0>(b) ? TBBT_HEAVY(s) : (b)>0 ? TBBT_HEAVY(Other(s)) : 0 ) \
74  | ( (i) ? TBBT_INTERN : 0 ) )
75  };
76 
77 /* Pointer to the tbbt node free list */
78 static TBBT_NODE *tbbt_free_list=NULL;
79 
80 typedef struct tbbt_tree TBBT_TREE;
81 /* Threaded tree structure */
82 struct tbbt_tree
83  {
84  TBBT_NODE *root;
85  unsigned long count; /* The number of nodes in the tree currently */
86  uintn fast_compare; /* use a faster in-line compare (with casts) instead of function call */
87  intn (*compar) (VOIDP k1, VOIDP k2, intn cmparg);
88  intn cmparg;
89 #endif /* TBBT_INTERNALS */
90  };
91 
92 /* Define the "fast compare" values */
93 #define TBBT_FAST_UINT16_COMPARE 1
94 #define TBBT_FAST_INT32_COMPARE 2
95 
96 #ifndef TBBT_INTERNALS
97 typedef TBBT_NODE **TBBT_TREE;
98 #endif /* TBBT_INTERNALS */
99 
100 /* Return maximum of two scalar values (use arguments w/o side effects): */
101 #define Max(a,b) ( (a) > (b) ? (a) : (b) )
102 
103 /* These routines are designed to allow use of a general-purpose balanced tree
104  * implimentation. These trees are appropriate for maintaining in memory one
105  * or more lists of items, each list sorted according to key values (key values
106  * must form a "completely ordered set") where no two items in a single list
107  * can have the same key value. The following operations are supported:
108  * Create an empty list
109  * Add an item to a list
110  * Look up an item in a list by key value
111  * Look up the Nth item in a list
112  * Delete an item from a list
113  * Find the first/last/next/previous item in a list
114  * Destroy a list
115  * Each of the above operations requires Order(log(N)) time where N is the
116  * number of items in the list (except for list creation which requires
117  * constant time and list destruction which requires Order(N) time if the user-
118  * supplied free-data-item or free-key-value routines require constant time).
119  * Each of the above operations (except create and destroy) can be performed
120  * on a subtree.
121  *
122  * Each node of a tree has associated with it a generic pointer (void *) which
123  * is set to point to one such "item" and a generic pointer to point to that
124  * item's "key value". The structure of the items and key values is up to the
125  * user to define. The user must specify a method for comparing key values.
126  * This routine takes three arguments, two pointers to key values and a third
127  * integer argument. You can specify a routine that expects pointers to "data
128  * items" rather than key values in which case the pointer to the key value in
129  * each node will be set equal to the pointer to the data item.
130  *
131  * Since the "data item" pointer is the first field of each tree node, these
132  * routines may be used without this "tbbt.h" file. For example, assume "ITM"
133  * is the structre definition for the data items you want to store in lists:
134  * ITM ***tbbtdmake( int (*cmp)(void *,void *,int), int arg );
135  * ITM **root= NULL; (* How to create an empty tree w/o tbbtdmake() *)
136  * ITM **tbbtdfind( ITM ***tree, void *key, ITM ***pp );
137  * ITM **tbbtfind( ITM **root, void *key, int (*cmp)(), int arg, ITM ***pp );
138  * ITM **tbbtdless( ITM ***tree, void *key, ITM ***pp );
139  * ITM **tbbtless( ITM **root, void *key, int (*cmp)(), int arg, ITM ***pp );
140  * ITM **tbbtindx( ITM **root, long indx );
141  * ITM **tbbtdins( ITM ***tree, ITM *item, void *key );
142  * ITM **tbbtins( ITM ***root, ITM *item, void *key, int (*cmp)(), int arg );
143  * ITM *tbbtrem( ITM ***root, ITM **node, void **kp );
144  * ITM **tbbtfirst( ITM **root ), **tbbtlast( ITM **root );
145  * ITM **tbbtnext( ITM **node ), **tbbtprev( ITM **node );
146  * ITM ***tbbtdfree( ITM ***tree, void (*df)(ITM *), void (*kf)(void *) );
147  * void tbbtfree( ITM ***root, void (*df)(ITM *), void (*kf)(void *) );
148  */
149 
150 #if defined c_plusplus || defined __cplusplus
151 extern "C"
152 {
153 #endif /* c_plusplus || __cplusplus */
154 
156  (intn (*compar) (VOIDP, VOIDP, intn), intn arg, uintn fast_compare);
157 /* Allocates and initializes an empty threaded, balanced, binary tree and
158  * returns a pointer to the control structure for it. You can also create
159  * empty trees without this function as long as you never use tbbtd* routines
160  * (tbbtdfind, tbbtdins, tbbtdfree) on them.
161  * Examples:
162  * int keycmp();
163  * TBBT_ROOT *root= tbbtdmake( keycmp, (int)keysiz , 0);
164  * or
165  * void *root= tbbtdmake( strcmp, 0 , 0);
166  * or
167  * void *root= tbbtdmake( keycmp, (int)keysiz , TBBT_FAST_UINT16_COMPARE);
168  * or
169  * TBBT_NODE *root= NULL; (* Don't use tbbtd* routines *)
170  * `cmp' is the routine to be used to compare two key values [in tbbtdfind()
171  * and tbbtdins()]. The arguments to `cmp' are the two keys to compare
172  * and `arg': (*cmp)(k1,k2,arg). `cmp' is expected to return 0 if its first
173  * two arguments point to identical key values, -1 (or any integer less than 0)
174  * if k1 points to a key value lower than that pointed to by k2, and 1 (or any
175  * integer greater than 0) otherwise. If `cmp' is NULL, memcmp is used. If
176  * `cmp' is NULL and `arg' is not greater than 0L, `1+strlen(key1)' is used in
177  * place of `arg' to emulate strcmp(): memcmp( k1, k2, 1+strlen(k1) ). You
178  * can use strcmp() directly (as in the second example above) as long as your C
179  * compiler does not assume strcmp() will always be passed exactly 2 arguments
180  * (only newer, ANSI-influenced C compilers are likely to be able to make this
181  * kind of assumption). You can also use a key comparison routine that expects
182  * pointers to data items rather than key values.
183  * The "fast compare" option is for keys of simple numeric types (currently
184  * uint16 and int32) and avoids the function call for faster searches in
185  * some cases. The key comparison routine is still required for some
186  * insertion routines which use it.
187  *
188  * Most of the other routines expect a pointer to a root node of a tree, not
189  * a pointer to the tree's control structure (only tbbtdfind(), tbbtdins(),
190  * and tbbtdfree() expect pointers to control structures). However TBBT_TREE
191  * is just defined as "**TBBT_NODE" (unless you have defined TBBT_INTERNALS so
192  * you have access to the internal structure of the nodes) so
193  * TBBT_TREE *tree1= tbbtdmake( NULL, 0 );
194  * is equivalent to
195  * TBBT_NODE **tree1= tbbtdmake( NULL, 0 );
196  * So could be used as:
197  * node= tbbtdfind( tree1, key, NULL );
198  * node= tbbtfind( *tree1, key, compar, arg, NULL );
199  * node= tbbtdless( tree1, key, NULL );
200  * node= tbbtless( *tree1, key, compar, arg, NULL );
201  * node= tbbtdins( tree1, item, key );
202  * node= tbbtins( tree1, item, key, compar, arg );
203  * item= tbbtrem( tree1, tbbtdfind(tree1,key,NULL), NULL );
204  * item= tbbtrem( tree1, tbbtfind(*tree1,key,compar,arg,NULL), NULL );
205  * tree1= tbbtdfree( tree1, free, NULL ); (* or whatever *)
206  * while
207  * TBBT_NODE *root= NULL;
208  * would be used like:
209  * node= tbbtfind( root, key );
210  * node= tbbtins( &root, item, key );
211  * node= tbbtrem( &root, tbbtfind(root,key), NULL );
212  * tbbtfree( &root, free, NULL ); (* or whatever *)
213  * Never use tbbtfree() on a tree allocated with tbbtdmake() or on a sub-tree
214  * of ANY tree. Never use tbbtdfree() except on a tbbtdmake()d tree.
215  */
216 
218  (TBBT_TREE * tree, VOIDP key, TBBT_NODE ** pp);
220  (TBBT_NODE * root, VOIDP key, intn (*cmp) (VOIDP, VOIDP, intn),
221  intn arg, TBBT_NODE ** pp);
223  (TBBT_TREE * tree, VOIDP key, TBBT_NODE ** pp);
225  (TBBT_NODE * root, VOIDP key, intn (*cmp) (VOIDP, VOIDP, intn),
226  intn arg, TBBT_NODE ** pp);
227 /* Locate a node based on the key given. A pointer to the node in the tree
228  * with a key value matching `key' is returned. If no such node exists, NULL
229  * is returned. Whether a node is found or not, if `pp' is not NULL, `*pp'
230  * will be set to point to the parent of the node we are looking for (or that
231  * node that would be the parent if the node is not found). tbbtdfind() is
232  * used on trees created using tbbtdmake() (so that `cmp' and `arg' don't have
233  * to be passed). tbbtfind() can be used on the root or any subtree of a tree
234  * create using tbbtdmake() and is used on any tree (or subtree) created with-
235  * out using tbbtdmake(). tbbtless() & tbbtdless() work exactly like tbbtfind()
236  * and tbbtdfind() except that they find the node with a key which is less than
237  * or equal to the key given to them.
238  */
239 
241  (TBBT_NODE * root, int32 indx);
242 /* Locate the node that has `indx' nodes with lesser key values. This is like
243  * an array lookup with the first item in the list having index 0. For large
244  * values of `indx', this call is much faster than tbbtfirst() followed by
245  * `indx' tbbtnext()s. Thus `tbbtindx(&root,0L)' is equivalent to (and almost
246  * as fast as) `tbbtfirst(root)'.
247  */
248 
250  (TBBT_TREE * tree, VOIDP item, VOIDP key);
252  (TBBT_NODE ** root, VOIDP item, VOIDP key, intn (*cmp) (VOIDP, VOIDP, intn), intn arg);
253 /* Insert a new node to the tree having a key value of `key' and a data pointer
254  * of `item'. If a node already exists in the tree with key value `key' or if
255  * malloc() fails, NULL is returned (no node is inserted), otherwise a pointer
256  * to the inserted node is returned. `cmp' and `arg' are as for tbbtfind().
257  */
258 
259 HDFLIBAPI VOIDP tbbtrem
260  (TBBT_NODE ** root, TBBT_NODE * node, VOIDP *kp);
261 /* Remove the node pointed to by `node' from the tree with root `root'. The
262  * data pointer for the deleted node is returned. If the second argument is
263  * NULL, NULL is returned. If `kp' is not NULL, `*kp' is set to point to the
264  * key value for the deleted node. Examples:
265  * data= tbbtrem( tree, tbbtdfind(tree,key), &kp ); free(data); free(kp);
266  * data= tbbtrem( &root, tbbtfind(root,key,compar,arg), NULL );
267  * data= tbbtrem( &tree->root, tbbtdfind(tree,key), NULL );
268  */
269 
271  (TBBT_NODE * root);
273  (TBBT_NODE * root);
274 /* Returns a pointer to node from the tree with the lowest(first)/highest(last)
275  * key value. If the tree is empy NULL is returned. Examples:
276  * node= tbbtfirst(*tree);
277  * node= tbbtfirst(root);
278  * node= tbbtlast(tree->root);
279  * node= tbbtlast(node); (* Last node in a sub-tree *)
280  */
281 
283  (TBBT_NODE * node);
285  (TBBT_NODE * node);
286 /* Returns a pointer the node from the tree with the next highest (previous
287  * lowest) key value relative to the node pointed to by `node'. If `node'
288  * points the last (first) node of the tree, NULL is returned.
289  */
290 
292  (TBBT_TREE * tree, VOID(*fd) (VOIDP), VOID(*fk) (VOIDP));
293 HDFLIBAPI VOID tbbtfree
294  (TBBT_NODE ** root, VOID(*fd) (VOIDP), VOID(*fk) (VOIDP));
295 /* Frees up an entire tree. `fd' is a pointer to a function that frees/
296  * destroys data items, and `fk' is the same for key values.
297  * void free();
298  * tree= tbbtdfree( tree, free, free );
299  * tbbtfree( &root, free, free );
300  * is a typical usage, where keys and data are individually malloc()d. If `fk'
301  * is NULL, no action is done for the key values (they were allocated on the
302  * stack, as a part of each data item, or together with one malloc() call, for
303  * example) and likewise for `fd'. tbbtdfree() always returns NULL and
304  * tbbtfree() always sets `root' to be NULL.
305  */
306 
307 HDFLIBAPI VOID tbbtprint
308  (TBBT_NODE * node);
309 /* Prints out the data in a node */
310 
311 HDFLIBAPI VOID tbbtdump
312  (TBBT_TREE * tree, intn method);
313 /* Prints an entire tree. The method variable determines which sort of
314  * traversal is used:
315  * -1 : Pre-Order Traversal
316  * 1 : Post-Order Traversal
317  * 0 : In-Order Traversal
318  */
319 
320 HDFLIBAPI long tbbtcount
321  (TBBT_TREE * tree);
322 
323 /* Terminate the buffers used in the tbbt*() interface */
324 HDFPUBLIC intn tbbt_shutdown(void);
325 
326 #if defined c_plusplus || defined __cplusplus
327 }
328 #endif /* c_plusplus || __cplusplus */
329 
330 #endif /* TBBT_H */
HDFFCLIBAPI intf intf intf * count
HDFLIBAPI TBBT_NODE * tbbtnext(TBBT_NODE *node)
HDFLIBAPI TBBT_NODE * tbbtprev(TBBT_NODE *node)
HDFLIBAPI TBBT_NODE * tbbtlast(TBBT_NODE *root)
HDFLIBAPI TBBT_NODE * tbbtless(TBBT_NODE *root, VOIDP key, intn(*cmp)(VOIDP, VOIDP, intn), intn arg, TBBT_NODE **pp)
HDFLIBAPI TBBT_NODE * tbbtindx(TBBT_NODE *root, int32 indx)
HDFLIBAPI TBBT_NODE * tbbtdfind(TBBT_TREE *tree, VOIDP key, TBBT_NODE **pp)
Definition: tbbt.h:31
HDFLIBAPI TBBT_NODE * tbbtins(TBBT_NODE **root, VOIDP item, VOIDP key, intn(*cmp)(VOIDP, VOIDP, intn), intn arg)
HDFLIBAPI VOIDP tbbtrem(TBBT_NODE **root, TBBT_NODE *node, VOIDP *kp)
TBBT_NODE ** TBBT_TREE
Definition: tbbt.h:97
HDFLIBAPI TBBT_NODE * tbbtfirst(TBBT_NODE *root)
HDFLIBAPI TBBT_NODE * tbbtdless(TBBT_TREE *tree, VOIDP key, TBBT_NODE **pp)
VOIDP key
Definition: tbbt.h:34
HDFLIBAPI VOID tbbtprint(TBBT_NODE *node)
HDFLIBAPI long tbbtcount(TBBT_TREE *tree)
HDFPUBLIC intn tbbt_shutdown(void)
HDFLIBAPI TBBT_TREE * tbbtdmake(intn(*compar)(VOIDP, VOIDP, intn), intn arg, uintn fast_compare)
VOIDP data
Definition: tbbt.h:33
HDFLIBAPI TBBT_NODE * tbbtfind(TBBT_NODE *root, VOIDP key, intn(*cmp)(VOIDP, VOIDP, intn), intn arg, TBBT_NODE **pp)
#define HDFPUBLIC
Definition: H4api_adpt.h:194
HDFLIBAPI VOID tbbtdump(TBBT_TREE *tree, intn method)
HDFFCLIBAPI intf intf * flags
char * arg
Definition: cdjpeg.h:136
#define HDFLIBAPI
Definition: H4api_adpt.h:195
HDFLIBAPI TBBT_NODE * tbbtdins(TBBT_TREE *tree, VOIDP item, VOIDP key)
HDFLIBAPI TBBT_TREE * tbbtdfree(TBBT_TREE *tree, VOID(*fd)(VOIDP), VOID(*fk)(VOIDP))
HDFLIBAPI VOID tbbtfree(TBBT_NODE **root, VOID(*fd)(VOIDP), VOID(*fk)(VOIDP))

MISR Toolkit - Copyright © 2005 - 2020 Jet Propulsion Laboratory
Generated on Fri Jun 19 2020 22:49:52