57cc5b44f21ef69478ecbd2261f2e64298bb674d
2 * Austin---Astonishing Universal Search Tree Interface Novelty
3 * Copyright (C) 2000 Kaz Kylheku <kaz@ashi.footprints.net>
5 * Free Software License:
7 * All rights are reserved by the author, with the following exceptions:
8 * Permission is granted to freely reproduce and distribute this software,
9 * possibly in exchange for a fee, provided that this copyright notice appears
10 * intact. Permission is also granted to adapt this software to produce
11 * derivative works, as long as the modified versions carry this copyright
12 * notice and additional notices stating that the work has been modified.
13 * This source code may be translated into executable form and incorporated
14 * into proprietary software; there is no requirement for such software to
15 * contain a copyright notice related to this source.
17 * $Id: tree.c,v 1.8 1999/12/09 05:38:52 kaz Exp $
21 * Modified for use in ReactOS by arty
28 void udict_tree_delete(udict_t
*ud
, udict_node_t
*node
, udict_node_t
**pswap
, udict_node_t
**pchild
)
30 udict_node_t
*nil
= tree_null_priv(ud
), *child
, *delparent
= node
->parent
;
31 udict_node_t
*next
= node
, *nextparent
;
33 if( tree_root_priv(ud
) == node
)
34 delparent
= &ud
->BalancedRoot
;
36 if (node
->left
!= nil
&& node
->right
!= nil
) {
37 next
= udict_tree_next(ud
, node
);
38 nextparent
= next
->parent
;
40 if( tree_root_priv(ud
) == next
)
41 nextparent
= &ud
->BalancedRoot
;
44 assert (next
->parent
!= nil
);
45 assert (next
->left
== nil
);
48 * First, splice out the successor from the tree completely, by
49 * moving up its right child into its place.
53 child
->parent
= nextparent
;
55 if (nextparent
->left
== next
) {
56 nextparent
->left
= child
;
58 assert (nextparent
->right
== next
);
59 nextparent
->right
= child
;
63 * Now that the successor has been extricated from the tree, install it
64 * in place of the node that we want deleted.
67 next
->parent
= delparent
;
68 next
->left
= node
->left
;
69 next
->right
= node
->right
;
70 next
->left
->parent
= next
;
71 next
->right
->parent
= next
;
73 if (delparent
->left
== node
) {
74 delparent
->left
= next
;
76 assert (delparent
->right
== node
);
77 delparent
->right
= next
;
82 assert (node
->left
== nil
|| node
->right
== nil
);
84 child
= (node
->left
!= nil
) ? node
->left
: node
->right
;
85 child
->parent
= delparent
= node
->parent
;
87 if (node
== delparent
->left
) {
88 delparent
->left
= child
;
90 assert (node
== delparent
->right
);
91 delparent
->right
= child
;
105 udict_node_t
*udict_tree_lookup(udict_t
*ud
, const void *_key
)
107 udict_node_t
*root
= tree_root_priv(ud
);
108 udict_node_t
*nil
= tree_null_priv(ud
);
111 /* simple binary search adapted for trees that contain duplicate keys */
113 while (root
!= nil
) {
114 result
= ud
->compare(ud
, (void *)_key
, key(root
));
127 udict_node_t
*udict_tree_lower_bound(udict_t
*ud
, const void *_key
)
129 udict_node_t
*root
= tree_root_priv(ud
);
130 udict_node_t
*nil
= tree_null_priv(ud
);
131 udict_node_t
*tentative
= 0;
133 while (root
!= nil
) {
134 int result
= ud
->compare(ud
, (void *)_key
, key(root
));
138 } else if (result
< 0) {
149 udict_node_t
*udict_tree_upper_bound(udict_t
*ud
, const void *_key
)
151 udict_node_t
*root
= tree_root_priv(ud
);
152 udict_node_t
*nil
= tree_null_priv(ud
);
153 udict_node_t
*tentative
= 0;
155 while (root
!= nil
) {
156 int result
= ud
->compare(ud
, (void *)_key
, key(root
));
160 } else if (result
> 0) {
171 udict_node_t
*udict_tree_first(udict_t
*ud
)
173 udict_node_t
*nil
= tree_null_priv(ud
), *root
= tree_root_priv(ud
), *left
;
176 while ((left
= root
->left
) != nil
)
179 return (root
== nil
) ? 0 : root
;
182 udict_node_t
*udict_tree_last(udict_t
*ud
)
184 udict_node_t
*nil
= tree_null_priv(ud
), *root
= tree_root_priv(ud
), *right
;
187 while ((right
= root
->right
) != nil
)
190 return (root
== nil
) ? 0 : root
;
193 udict_node_t
*udict_tree_next(udict_t
*ud
, udict_node_t
*curr
)
195 udict_node_t
*nil
= tree_null_priv(ud
), *parent
, *left
;
197 if (curr
->right
!= nil
) {
199 while ((left
= curr
->left
) != nil
)
204 parent
= curr
->parent
;
206 while (parent
!= nil
&& curr
== parent
->right
) {
208 parent
= curr
->parent
;
211 return (parent
== nil
) ? 0 : parent
;
214 udict_node_t
*udict_tree_prev(udict_t
*ud
, udict_node_t
*curr
)
216 udict_node_t
*nil
= tree_null_priv(ud
), *parent
, *right
;
218 if (curr
->left
!= nil
) {
220 while ((right
= curr
->right
) != nil
)
225 parent
= curr
->parent
;
227 while (parent
!= nil
&& curr
== parent
->left
) {
229 parent
= curr
->parent
;
232 return (parent
== nil
) ? 0 : parent
;
236 * Perform a ``left rotation'' adjustment on the tree. The given parent node P
237 * and its right child C are rearranged so that the P instead becomes the left
238 * child of C. The left subtree of C is inherited as the new right subtree
239 * for P. The ordering of the keys within the tree is thus preserved.
242 void udict_tree_rotate_left(udict_node_t
*child
, udict_node_t
*parent
)
244 udict_node_t
*leftgrandchild
, *grandpa
;
246 assert (parent
->right
== child
);
248 child
= parent
->right
;
249 parent
->right
= leftgrandchild
= child
->left
;
250 leftgrandchild
->parent
= parent
;
252 child
->parent
= grandpa
= parent
->parent
;
254 if (parent
== grandpa
->left
) {
255 grandpa
->left
= child
;
257 assert (parent
== grandpa
->right
);
258 grandpa
->right
= child
;
261 child
->left
= parent
;
262 parent
->parent
= child
;
267 * This operation is the ``mirror'' image of rotate_left. It is
268 * the same procedure, but with left and right interchanged.
271 void udict_tree_rotate_right(udict_node_t
*child
, udict_node_t
*parent
)
273 udict_node_t
*rightgrandchild
, *grandpa
;
275 assert (parent
->left
== child
);
277 parent
->left
= rightgrandchild
= child
->right
;
278 rightgrandchild
->parent
= parent
;
280 child
->parent
= grandpa
= parent
->parent
;
282 if (parent
== grandpa
->right
) {
283 grandpa
->right
= child
;
285 assert (parent
== grandpa
->left
);
286 grandpa
->left
= child
;
289 child
->right
= parent
;
290 parent
->parent
= child
;