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