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