README.rb

Tue, 24 Apr 2007 19:00:47 +0200

author
Tuomo Valkonen <tuomov@iki.fi>
date
Tue, 24 Apr 2007 19:00:47 +0200
changeset 110
13134ea30227
parent 65
58e382ae97cd
permissions
-rw-r--r--

Oops, fixed comparison function order.

65
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
1 Generic C code for red-black trees.
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
2 Copyright (C) 2000 James S. Plank
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
3
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
4 This library is free software; you can redistribute it and/or
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
5 modify it under the terms of the GNU Lesser General Public
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
6 License as published by the Free Software Foundation; either
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
7 version 2.1 of the License, or (at your option) any later version.
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
8
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
9 This library is distributed in the hope that it will be useful,
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
12 Lesser General Public License for more details.
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
13
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
14 You should have received a copy of the GNU Lesser General Public
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
15 License along with this library; if not, write to the Free Software
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
17
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
18 ---------------------------------------------------------------------------
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
19 Jim Plank
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
20 plank@cs.utk.edu
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
21 http://www.cs.utk.edu/~plank
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
22
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
23 Department of Computer Science
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
24 University of Tennessee
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
25 107 Ayres Hall
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
26 Knoxville, TN 37996
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
27
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
28 615-974-4397
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
29 $Revision: 1.2 $
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
30 ---------------------------------------------------------------------------
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
31
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
32 Rb.c and rb.h are files for doing general red-black trees.
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
33
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
34 The directory ansi contains ansi-standard c code for rb-trees (there
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
35 are some gross pointer casts there but don't worry about them. They
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
36 work). The directory non-ansi contains straight c code for rb-trees.
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
37 The ansi version can also be used by c++ (it has been tested).
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
38
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
39 Rb.h contains the typedef for red-black tree structures. Basically,
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
40 red-black trees are balanced trees whose external nodes are sorted
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
41 by a key, and connected in a linked list. The following is how
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
42 you use rb.c and rb.h:
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
43
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
44 Include rb.h in your source.
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
45
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
46 Make_rb() returns the head of a red-black tree. It serves two functions:
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
47 Its p.root pointer points to the root of the red-black tree. Its
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
48 c.list.flink and c.list.blink pointers point to the first and last
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
49 external nodes of the tree. When the tree is empty, all these pointers
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
50 point to itself.
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
51
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
52 The external nodes can be traversed in sorted order with their
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
53 c.list.flink and c.list.blink pointers. The macros rb_first, rb_last,
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
54 rb_next, rb_prev, and rb_traverse can be used to traverse external node lists.
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
55
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
56 External nodes hold two pieces of information: the key and the value
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
57 (in k.key and v.val, respectively). The key can be a character
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
58 string, an integer, or a general pointer. Val is typed as a character
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
59 pointer, but can be any pointer. If the key is a character string,
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
60 then one can insert it, and a value into a tree with rb_insert(). If
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
61 it is an integer, then rb_inserti() should be used. If it is a general
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
62 pointer, then rb_insertg() must be used, with a comparison function
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
63 passed as the fourth argument. This function takes two keys as arguments,
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
64 and returns a negative value, positive value, or 0, depending on whether
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
65 the first key is less than, greater than or equal to the second. Thus,
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
66 one could use rb_insertg(t, s, v, strcmp) to insert the value v with
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
67 a character string s into the tree t.
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
68
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
69 Rb_find_key(t, k) returns the external node in t whose value is equal
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
70 k or whose value is the smallest value greater than k. (Here, k is
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
71 a string). If there is no value greater than or equal to k, then
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
72 t is returned. Rb_find_ikey(t,k) works when k is an integer, and
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
73 Rb_find_gkey(t,k,cmp) works for general pointers.
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
74
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
75 Rb_find_key_n(t, k, n) is the same as rb_find_key, except that it
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
76 returns whether or not k was found in n (n is an int *). Rb_find_ikey_n
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
77 and Rb_find_gkey_n are the analogous routines for integer and general
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
78 keys.
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
79
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
80 Rb_insert_b(e, k, v) makes a new external node with key k and val v, and
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
81 inserts it before the external node e. If e is the head of a tree,
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
82 then the new node is inserted at the end of the external node list.
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
83 If this insertion violates sorted order, no error is flagged. It is
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
84 assumed that the user knows what he/she is doing. Rb_insert_a(e,k,v)
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
85 inserts the new node after e (if e = t, it inserts the new node at the
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
86 beginning of the list).
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
87
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
88 Rb_insert() is therefore really a combination of Rb_find_key() and
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
89 Rb_insert_b().
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
90
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
91 Rb_delete_node(e) deletes the external node e from a tree (and thus from
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
92 the linked list of external nodes). The node is free'd as well, so
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
93 don't retain pointers to it.
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
94
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
95 Red-black trees are spiffy because find_key, insert, and delete are all
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
96 done in log(n) time. Thus, they can be freely used instead of hash-tables,
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
97 with the benifit of having the elements in sorted order at all times, and
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
98 with the guarantee of operations being in log(n) time.
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
99
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
100 Other routines:
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
101
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
102 Rb_print_tree() will grossly print out a red-black tree with string keys.
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
103 Rb_iprint_tree() will do the same with trees with integer keys.
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
104 Rb_nblack(e) will report the number of black nodes on the path from external
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
105 node e to the root. The path length is less than twice this value.
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
106 Rb_plength(e) reports the length of the path from e to the root.
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
107
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
108
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
109 You can find a general description of red-black trees in any basic algorithms
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
110 text. E.g. ``Introduction to Algorithms'', by Cormen, Leiserson and Rivest
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
111 (McGraw Hill). An excellent and complete description of red-black trees
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
112 can also be found in Chapter 1 of Heather Booth's PhD disseratation:
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
113 ``Some Fast Algorithms on Graphs and Trees'', Princeton University, 1990.

mercurial