Wed, 10 Mar 2004 17:46:49 +0100
trunk: changeset 1370
- Added red-black tree routines for direct pointer comparison.
- Made keys to red-black tree routines const.
65 | 1 | /* |
2 | Generic C code for red-black trees. | |
3 | Copyright (C) 2000 James S. Plank | |
4 | ||
5 | This library is free software; you can redistribute it and/or | |
6 | modify it under the terms of the GNU Lesser General Public | |
7 | License as published by the Free Software Foundation; either | |
8 | version 2.1 of the License, or (at your option) any later version. | |
9 | ||
10 | This library is distributed in the hope that it will be useful, | |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 | Lesser General Public License for more details. | |
14 | ||
15 | You should have received a copy of the GNU Lesser General Public | |
16 | License along with this library; if not, write to the Free Software | |
17 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
18 | */ | |
19 | ||
20 | /* Revision 1.2. Jim Plank */ | |
21 | ||
22 | /* Original code by Jim Plank (plank@cs.utk.edu) */ | |
23 | /* modified for THINK C 6.0 for Macintosh by Chris Bartley */ | |
24 | ||
66 | 25 | typedef struct rb_status { |
65 | 26 | unsigned red : 1 ; |
27 | unsigned internal : 1 ; | |
28 | unsigned left : 1 ; | |
29 | unsigned root : 1 ; | |
30 | unsigned head : 1 ; | |
66 | 31 | } Rb_status; |
65 | 32 | |
33 | /* Main rb_node. You only ever use the fields | |
34 | ||
35 | c.list.flink | |
36 | c.list.blink | |
37 | ||
38 | k.key or k.ikey | |
39 | v.val | |
40 | */ | |
41 | ||
42 | ||
43 | typedef struct rb_node { | |
44 | union { | |
45 | struct { | |
46 | struct rb_node *flink; | |
47 | struct rb_node *blink; | |
48 | } list; | |
49 | struct { | |
50 | struct rb_node *left; | |
51 | struct rb_node *right; | |
52 | } child; | |
53 | } c; | |
54 | union { | |
55 | struct rb_node *parent; | |
56 | struct rb_node *root; | |
57 | } p; | |
66 | 58 | Rb_status s; |
65 | 59 | union { |
60 | int ikey; | |
67 | 61 | const void *key; |
65 | 62 | struct rb_node *lext; |
63 | } k; | |
64 | union { | |
66 | 65 | void *val; |
65 | 66 | struct rb_node *rext; |
67 | } v; | |
68 | } *Rb_node; | |
69 | ||
70 | ||
67 | 71 | typedef int Rb_compfn(const void *, const void *); |
65 | 72 | |
73 | ||
66 | 74 | extern Rb_node make_rb(); /* Creates a new rb-tree */ |
65 | 75 | |
76 | /* Creates a node with key key and val val and inserts it into the tree. | |
77 | rb_insert uses strcmp() as comparison funcion. rb_inserti uses <>=, | |
78 | rb_insertg uses func() */ | |
79 | ||
67 | 80 | extern Rb_node rb_insert(Rb_node tree, const char *key, void *val); |
66 | 81 | extern Rb_node rb_inserti(Rb_node tree, int ikey, void *val); |
67 | 82 | extern Rb_node rb_insertp(Rb_node tree, const void *key, void *val); |
83 | extern Rb_node rb_insertg(Rb_node tree, const void *key, void *val, | |
84 | Rb_compfn *func); | |
65 | 85 | |
86 | ||
87 | /* returns an external node in t whose value is equal | |
88 | k or whose value is the smallest value greater than k. */ | |
89 | ||
67 | 90 | extern Rb_node rb_find_key(Rb_node root, const char *key); |
65 | 91 | extern Rb_node rb_find_ikey(Rb_node root, int ikey); |
67 | 92 | extern Rb_node rb_find_pkey(Rb_node root, const void *key); |
93 | extern Rb_node rb_find_gkey(Rb_node root, const void *key, Rb_compfn *func); | |
65 | 94 | |
95 | ||
96 | /* Works just like the find_key versions only it returns whether or not | |
97 | it found the key in the integer variable found */ | |
98 | ||
67 | 99 | extern Rb_node rb_find_key_n(Rb_node root, const char *key, int *found); |
65 | 100 | extern Rb_node rb_find_ikey_n(Rb_node root, int ikey, int *found); |
67 | 101 | extern Rb_node rb_find_pkey_n(Rb_node root, const void *key, int *found); |
102 | extern Rb_node rb_find_gkey_n(Rb_node root, const void *key, | |
103 | Rb_compfn *func, int *found); | |
65 | 104 | |
105 | ||
106 | /* Creates a node with key key and val val and inserts it into the | |
107 | tree before/after node nd. Does not check to ensure that you are | |
108 | keeping the correct order */ | |
109 | ||
67 | 110 | extern Rb_node rb_insert_b(Rb_node nd, const void *key, void *val); |
111 | extern Rb_node rb_insert_a(Rb_node nd, const void *key, void *val); | |
65 | 112 | |
113 | ||
114 | extern void rb_delete_node(Rb_node node); /* Deletes and frees a node (but | |
115 | not the key or val) */ | |
116 | extern void rb_free_tree(Rb_node root); /* Deletes and frees an entire tree */ | |
117 | ||
66 | 118 | extern void *rb_val(Rb_node node); /* Returns node->v.val -- this is to shut |
65 | 119 | lint up */ |
120 | ||
121 | extern int rb_nblack(Rb_node n); /* returns # of black nodes in path from | |
122 | n to the root */ | |
123 | int rb_plength(Rb_node n); /* returns the # of nodes in path from | |
124 | n to the root */ | |
125 | ||
126 | #define rb_first(n) (n->c.list.flink) | |
127 | #define rb_last(n) (n->c.list.blink) | |
128 | #define rb_next(n) (n->c.list.flink) | |
129 | #define rb_prev(n) (n->c.list.blink) | |
130 | #define rb_empty(t) (t->c.list.flink == t) | |
131 | #ifndef rb_nil | |
132 | #define rb_nil(t) (t) | |
133 | #endif | |
134 | ||
135 | #define rb_traverse(ptr, lst) \ | |
136 | for(ptr = rb_first(lst); ptr != rb_nil(lst); ptr = rb_next(ptr)) | |
137 |