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