1 // vi:ft=cpp
2 /**
3 * \file
4 * \brief AVL tree
5 */
6 /*
7 * (c) 2008-2009 Alexander Warg <warg@os.inf.tu-dresden.de>,
8 * Carsten Weinhold <weinhold@os.inf.tu-dresden.de>
9 * economic rights: Technische Universität Dresden (Germany)
10 *
11 * This file is part of TUD:OS and distributed under the terms of the
12 * GNU General Public License 2.
13 * Please see the COPYING-GPL-2 file for details.
14 *
15 * As a special exception, you may use this file as part of a free software
16 * library without restriction. Specifically, if other files instantiate
17 * templates or use macros or inline functions from this file, or you compile
18 * this file and link it with other files to produce an executable, this
19 * file does not by itself cause the resulting executable to be covered by
20 * the GNU General Public License. This exception does not however
21 * invalidate any other reasons why the executable file might be covered by
22 * the GNU General Public License.
23 */
24 #pragma once
25
26 #include "../type_traits"
27 #include "bst_base.h"
28 #include "bst_iter.h"
29
30 namespace cxx { namespace Bits {
31
32 /**
33 * \brief Basic binary search tree (BST).
34 *
35 * This class is intended as a base class for concrete binary search trees,
36 * such as an AVL tree. This class already provides the basic lookup methods
37 * and iterator definitions for a BST.
38 */
39 template< typename Node, typename Get_key, typename Compare >
40 class Bst
41 {
42 private:
43 typedef Direction Dir;
44 /// Ops for forward iterators
45 struct Fwd
46 {
childFwd47 static Node *child(Node const *n, Direction d)
48 { return Bst_node::next<Node>(n, d); }
49
cmpFwd50 static bool cmp(Node const *l, Node const *r)
51 { return Compare()(Get_key::key_of(l), Get_key::key_of(r)); }
52 };
53
54 /// Ops for Reverse iterators
55 struct Rev
56 {
childRev57 static Node *child(Node const *n, Direction d)
58 { return Bst_node::next<Node>(n, !d); }
59
cmpRev60 static bool cmp(Node const *l, Node const *r)
61 { return Compare()(Get_key::key_of(r), Get_key::key_of(l)); }
62 };
63
64 public:
65 /// The type of key values used to generate the total order of the elements.
66 typedef typename Get_key::Key_type Key_type;
67 /// The type for key parameters.
68 typedef typename Type_traits<Key_type>::Param_type Key_param_type;
69
70 /// Helper for building forward iterators for different wrapper classes.
71 typedef Fwd Fwd_iter_ops;
72 /// Helper for building reverse iterators for different wrapper classes.
73 typedef Rev Rev_iter_ops;
74
75 /// \name Iterators
76 //@{
77 /// Forward iterator.
78 typedef __Bst_iter<Node, Node, Fwd> Iterator;
79 /// Constant forward iterator.
80 typedef __Bst_iter<Node, Node const, Fwd> Const_iterator;
81 /// Backward iterator.
82 typedef __Bst_iter<Node, Node, Rev> Rev_iterator;
83 /// Constant backward.
84 typedef __Bst_iter<Node, Node const, Rev> Const_rev_iterator;
85 //@}
86
87 protected:
88 /**
89 * \name Interior access for descendants.
90 *
91 * As this class is an intended base class we provide protected access
92 * to our interior, use 'using' to make this private in concrete
93 * implementations.
94 */
95 /*@{*/
96
97 /// The head pointer of the tree.
98 Bst_node *_head;
99
100 /// Create an empty tree.
Bst()101 Bst() : _head(0) {}
102
103 /// Access the head node as object of type \a Node.
head()104 Node *head() const { return static_cast<Node*>(_head); }
105
106 /// Get the key value of \a n.
k(Bst_node const * n)107 static Key_type k(Bst_node const *n)
108 { return Get_key::key_of(static_cast<Node const *>(n)); }
109
110 /**
111 * \brief Get the direction to go from `l` to search for `r`.
112 * \param l is the key to look for.
113 * \param r is the key at the current position.
114 * \retval Direction::L for left
115 * \retval Direction::R for right
116 * \retval Direction::N if `l` is equal to `r`.
117 */
dir(Key_param_type l,Key_param_type r)118 static Dir dir(Key_param_type l, Key_param_type r)
119 {
120 Compare cmp;
121 Dir d(cmp(r, l));
122 if (d == Direction::L && !cmp(l, r))
123 return Direction::N;
124 return d;
125 }
126
127 /**
128 * \brief Get the direction to go from `l` to search for `r`.
129 * \param l is the key to look for.
130 * \param r is the node at the current position.
131 * \retval Direction::L For left.
132 * \retval Direction::R For right.
133 * \retval Direction::N If `l` is equal to `r`.
134 */
dir(Key_param_type l,Bst_node const * r)135 static Dir dir(Key_param_type l, Bst_node const *r)
136 { return dir(l, k(r)); }
137
138 /// Is \a l greater than \a r.
greater(Key_param_type l,Key_param_type r)139 static bool greater(Key_param_type l, Key_param_type r)
140 { return Compare()(r, l); }
141
142 /// Is \a l greater than \a r.
greater(Key_param_type l,Bst_node const * r)143 static bool greater(Key_param_type l, Bst_node const *r)
144 { return greater(l, k(r)); }
145
146 /// Is \a l greater than \a r.
greater(Bst_node const * l,Bst_node const * r)147 static bool greater(Bst_node const *l, Bst_node const *r)
148 { return greater(k(l), k(r)); }
149 /*@}*/
150
151 /**
152 * Remove all elements in the subtree of head.
153 *
154 * \param head Head of the the subtree to remove
155 * \param callback Optional function called on each removed element.
156 */
157 template<typename FUNC>
remove_tree(Bst_node * head,FUNC && callback)158 static void remove_tree(Bst_node *head, FUNC &&callback)
159 {
160 if (Bst_node *n = Bst_node::next(head, Dir::L))
161 remove_tree(n, callback);
162
163 if (Bst_node *n = Bst_node::next(head, Dir::R))
164 remove_tree(n, callback);
165
166 callback(static_cast<Node *>(head));
167 }
168
169 public:
170
171 /**
172 * \name Get default iterators for the ordered tree.
173 */
174 /*@{*/
175 /**
176 * \brief Get the constant forward iterator for the first element in the set.
177 * \return Constant forward iterator for the first element in the set.
178 */
begin()179 Const_iterator begin() const { return Const_iterator(head()); }
180 /**
181 * \brief Get the end marker for the constant forward iterator.
182 * \return The end marker for the constant forward iterator.
183 */
end()184 Const_iterator end() const { return Const_iterator(); }
185
186 /**
187 * \brief Get the mutable forward iterator for the first element of the set.
188 * \return The mutable forward iterator for the first element of the set.
189 */
begin()190 Iterator begin() { return Iterator(head()); }
191 /**
192 * \brief Get the end marker for the mutable forward iterator.
193 * \return The end marker for mutable forward iterator.
194 */
end()195 Iterator end() { return Iterator(); }
196
197 /**
198 * \brief Get the constant backward iterator for the last element in the set.
199 * \return The constant backward iterator for the last element in the set.
200 */
rbegin()201 Const_rev_iterator rbegin() const { return Const_rev_iterator(head()); }
202 /**
203 * \brief Get the end marker for the constant backward iterator.
204 * \return The end marker for the constant backward iterator.
205 */
rend()206 Const_rev_iterator rend() const { return Const_rev_iterator(); }
207
208 /**
209 * \brief Get the mutable backward iterator for the last element of the set.
210 * \return The mutable backward iterator for the last element of the set.
211 */
rbegin()212 Rev_iterator rbegin() { return Rev_iterator(head()); }
213 /**
214 * \brief Get the end marker for the mutable backward iterator.
215 * \return The end marker for mutable backward iterator.
216 */
rend()217 Rev_iterator rend() { return Rev_iterator(); }
218 /*@}*/
219
220
221 /**
222 * \name Lookup functions.
223 */
224 //@{
225 /**
226 * \brief find the node with the given \a key.
227 * \param key The key value of the element to search.
228 * \return A pointer to the node with the given \a key, or
229 * NULL if \a key was not found.
230 */
231 Node *find_node(Key_param_type key) const;
232
233 /**
234 * Find the first node with a key not less than the given `key`.
235 *
236 * \param key The key used for the search.
237 * \return A pointer to the found node, or `NULL` if no node was found.
238 */
239 Node *lower_bound_node(Key_param_type key) const;
240
241 /**
242 * \brief find the node with the given \a key.
243 * \param key The key value of the element to search.
244 * \return A valid iterator for the node with the given \a key,
245 * or an invalid iterator if \a key was not found.
246 */
247 Const_iterator find(Key_param_type key) const;
248
249 /**
250 * Clear the tree.
251 *
252 * \param callback Optional function to be called on each removed element.
253 *
254 * The callback may delete the elements. The function guarantees that
255 * the elements are no longer used after the callback has been called.
256 */
257 template<typename FUNC>
remove_all(FUNC && callback)258 void remove_all(FUNC &&callback)
259 {
260 if (!_head)
261 return;
262
263 Bst_node *head = _head;
264 _head = 0;
265 remove_tree(head, cxx::forward<FUNC>(callback));
266 }
267
268
269 //@}
270 };
271
272 /* find an element */
273 template< typename Node, typename Get_key, class Compare>
274 inline
275 Node *
find_node(Key_param_type key)276 Bst<Node, Get_key, Compare>::find_node(Key_param_type key) const
277 {
278 Dir d;
279
280 for (Bst_node *q = _head; q; q = Bst_node::next(q, d))
281 {
282 d = dir(key, q);
283 if (d == Dir::N)
284 return static_cast<Node*>(q);
285 }
286 return 0;
287 }
288
289 template< typename Node, typename Get_key, class Compare>
290 inline
291 Node *
lower_bound_node(Key_param_type key)292 Bst<Node, Get_key, Compare>::lower_bound_node(Key_param_type key) const
293 {
294 Dir d;
295 Bst_node *r = 0;
296
297 for (Bst_node *q = _head; q; q = Bst_node::next(q, d))
298 {
299 d = dir(key, q);
300 if (d == Dir::L)
301 r = q; // found a node greater than key
302 else if (d == Dir::N)
303 return static_cast<Node*>(q);
304 }
305 return static_cast<Node*>(r);
306 }
307
308 /* find an element */
309 template< typename Node, typename Get_key, class Compare>
310 inline
311 typename Bst<Node, Get_key, Compare>::Const_iterator
find(Key_param_type key)312 Bst<Node, Get_key, Compare>::find(Key_param_type key) const
313 {
314 Bst_node *q = _head;
315 Bst_node *r = q;
316
317 for (Dir d; q; q = Bst_node::next(q, d))
318 {
319 d = dir(key, q);
320 if (d == Dir::N)
321 return Iterator(static_cast<Node*>(q), static_cast<Node *>(r));
322
323 if (d != Dir::L && q == r)
324 r = Bst_node::next(q, d);
325 }
326 return Iterator();
327 }
328
329 }}
330