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)
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.
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.
31 #include "bits/bst_iter.h"
36 * \brief Node of an AVL tree.
38 class Avl_tree_node : public Bits::Bst_node
41 template< typename Node, typename Get_key, typename Compare >
42 friend class Avl_tree;
44 /// Shortcut for Balance values (we use Direction for that).
45 typedef Bits::Direction Bal;
46 /// Alias for Direction.
47 typedef Bits::Direction Dir;
49 // We are a final BST node, hide interior.
51 using Bits::Bst_node::next;
52 using Bits::Bst_node::next_p;
53 using Bits::Bst_node::rotate;
56 /// The balance value (#Direction::N is balanced).
60 /// Create an uninitialized node, this is what you should do.
65 Avl_tree_node(Avl_tree_node const &o);
67 /// private assignment for initialization and relinkage.
68 void operator = (Avl_tree_node const &o)
70 Bits::Bst_node::operator = (o);
71 _balance = o._balance;
74 /// Create an initialized node (for internal stuff).
75 explicit Avl_tree_node(bool) : Bits::Bst_node(true), _balance(Dir::N) {}
77 /// Double rotation of \a t.
78 static Bits::Bst_node *rotate2(Bst_node **t, Bal idir, Bal pre);
80 /// Is this subtree balanced?
81 bool balanced() const { return _balance == Bal::N; }
83 /// What is the balance of this subtree?
84 Bal balance() const { return _balance; }
86 /// Set the balance of this subtree to \a b.
87 void balance(Bal b) { _balance = b; }
92 * \brief A generic AVL tree.
93 * \tparam Node The data type of the nodes (must inherit from Avl_tree_node).
94 * \tparam Get_key The meta function to get the key value from a node.
95 * The implementation uses `Get_key::key_of(ptr_to_node)`. The
96 * type of the key values must be defined in `Get_key::Key_type`.
97 * \tparam Compare Binary relation to establish a total order for the
98 * nodes of the tree. `Compare()(l, r)` must return true if
99 * the key \a l is smaller than the key \a r.
101 * This implementation does not provide any memory management. It is the
102 * responsibility of the caller to allocate nodes before inserting them and
103 * to free them when they are removed or when the tree is destroyed.
104 * Conversely, the caller must also ensure that nodes are removed
105 * from the tree before they are destroyed.
107 template< typename Node, typename Get_key,
108 typename Compare = Lt_functor<typename Get_key::Key_type> >
109 class Avl_tree : public Bits::Bst<Node, Get_key, Compare>
112 typedef Bits::Bst<Node, Get_key, Compare> Bst;
114 /// Hide this from possible descendants.
117 /// Provide access to keys of nodes.
120 /// Alias type for balance values.
121 typedef typename Avl_tree_node::Bal Bal;
122 /// Alias type for Direction values.
123 typedef typename Avl_tree_node::Bal Dir;
125 /// Prohibit simple copy.
126 Avl_tree(Avl_tree const &o);
128 /// Prohibit simple copy.
129 void operator = (Avl_tree const &o);
133 typedef typename Bst::Key_type Key_type;
134 typedef typename Bst::Key_param_type Key_param_type;
137 // Grab iterator types from Bst
139 /// Forward iterator for the tree.
140 typedef typename Bst::Iterator Iterator;
141 /// Constant forward iterator for the tree.
142 typedef typename Bst::Const_iterator Const_iterator;
143 /// Backward iterator for the tree.
144 typedef typename Bst::Rev_iterator Rev_iterator;
145 /// Constant backward iterator for the tree.
146 typedef typename Bst::Const_rev_iterator Const_rev_iterator;
150 * \brief Insert a new node into this AVL tree.
151 * \param new_node A pointer to the new node.
152 * \return A pair, with \a second set to `true` and \a first pointing to
153 * \a new_node, on success. If there is already a node with the
154 * same key then \a first points to this node and \a second is 'false'.
156 Pair<Node *, bool> insert(Node *new_node);
159 * \brief Remove the node with \a key from the tree.
160 * \param key The key to the node to remove.
161 * \return The pointer to the removed node on success,
162 * or 0 if no node with the \a key exists.
164 Node *remove(Key_param_type key);
166 * \brief An alias for remove().
168 Node *erase(Key_param_type key) { return remove(key); }
170 /// Create an empty AVL tree.
171 Avl_tree() : Bst() {}
172 /// Destroy the tree.
175 this->remove_all([](Node *){});
178 #ifdef __DEBUG_L4_AVL
179 bool rec_dump(Avl_tree_node *n, int depth, int *dp, bool print, char pfx);
180 bool rec_dump(bool print)
183 return rec_dump(static_cast<Avl_tree_node *>(_head), 0, &dp, print, '+');
189 //----------------------------------------------------------------------------
190 /* IMPLEMENTATION: Bits::__Bst_iter_b */
195 Avl_tree_node::rotate2(Bst_node **t, Bal idir, Bal pre)
197 typedef Bits::Bst_node N;
198 typedef Avl_tree_node A;
199 N *tmp[2] = { *t, N::next(*t, idir) };
200 *t = N::next(tmp[1], !idir);
201 A *n = static_cast<A*>(*t);
203 N::next(tmp[0], idir, N::next(n, !idir));
204 N::next(tmp[1], !idir, N::next(n, idir));
205 N::next(n, !idir, tmp[0]);
206 N::next(n, idir, tmp[1]);
212 static_cast<A*>(tmp[0])->balance(Bal::N);
213 static_cast<A*>(tmp[1])->balance(Bal::N);
217 static_cast<A*>(tmp[pre != idir])->balance(!pre);
218 static_cast<A*>(tmp[pre == idir])->balance(Bal::N);
220 return N::next(tmp[pre == idir], !pre);
223 //----------------------------------------------------------------------------
224 /* Implementation of AVL Tree */
226 /* Insert new _Node. */
227 template< typename Node, typename Get_key, class Compare>
229 Avl_tree<Node, Get_key, Compare>::insert(Node *new_node)
231 typedef Avl_tree_node A;
232 typedef Bits::Bst_node N;
233 N **t = &_head; /* search variable */
234 N **s = &_head; /* node where rebalancing may occur */
235 Key_param_type new_key = Get_key::key_of(new_node);
237 // search insertion point
238 for (N *p; (p = *t);)
240 Dir b = this->dir(new_key, p);
242 return pair(static_cast<Node*>(p), false);
244 if (!static_cast<A const *>(p)->balanced())
250 *static_cast<A*>(new_node) = A(true);
254 A *a = static_cast<A*>(n);
257 A::Bal b(this->greater(new_key, n));
258 if (a->balance() != b)
260 // ok we got in balance the shorter subtree go higher
262 // propagate the new balance down to the new node
265 else if (b == Bal(this->greater(new_key, N::next(n, b))))
267 // left-left or right-right case -> single rotation
270 static_cast<A*>(*s)->balance(Bal::N);
275 // need a double rotation
276 n = N::next(N::next(n, b), !b);
277 n = A::rotate2(s, b, n == new_node ? Bal::N : Bal(this->greater(new_key, n)));
281 for (A::Bal b; n && n != new_node; static_cast<A*>(n)->balance(b), n = N::next(n, b))
282 b = Bal(this->greater(new_key, n));
284 return pair(new_node, true);
288 /* remove an element */
289 template< typename Node, typename Get_key, class Compare>
291 Node *Avl_tree<Node, Get_key, Compare>::remove(Key_param_type key)
293 typedef Avl_tree_node A;
294 typedef Bits::Bst_node N;
295 N **q = &_head; /* search variable */
296 N **s = &_head; /* last ('deepest') node on the search path to q
297 * with balance 0, at this place the rebalancing
298 * stops in any case */
302 // find target node and rebalancing entry
303 for (N *n; (n = *q); q = N::next_p(n, dir))
305 dir = Dir(this->greater(key, n));
306 if (dir == Dir::L && !this->greater(k(n), key))
310 if (!N::next(n, dir))
313 A const *a = static_cast<A const *>(n);
314 if (a->balanced() || (a->balance() == !dir && N::next<A>(n, !dir)->balanced()))
322 A *i = static_cast<A*>(*t);
324 for (N *n; (n = *s); s = N::next_p(n, dir))
326 dir = Dir(this->greater(key, n));
328 if (!N::next(n, dir))
331 A *a = static_cast<A*>(n);
332 // got one out of balance
335 else if (a->balance() == dir)
339 // we need rotations to get in balance
340 Bal b = N::next<A>(n, !dir)->balance();
342 A::rotate2(s, !dir, N::next<A>(N::next(n, !dir), dir)->balance());
349 static_cast<A*>(*s)->balance(Bal::N);
354 static_cast<A*>(*s)->balance(dir);
358 t = N::next_p(*s, dir);
362 A *n = static_cast<A*>(*q);
364 *q = N::next(n, !dir);
367 return static_cast<Node*>(i);
370 #ifdef __DEBUG_L4_AVL
371 template< typename Node, typename Get_key, class Compare>
372 bool Avl_tree<Node, Get_key, Compare>::rec_dump(Avl_tree_node *n, int depth, int *dp, bool print, char pfx)
374 typedef Avl_tree_node A;
379 int dpx[2] = {depth,depth};
382 res = rec_dump(n->next<A>(Dir::R), depth + 1, dpx + 1, print, '/');
386 fprintf(stderr, "%2d: [%8p] b=%1d: ", depth, n, (int)n->balance().d);
388 for (int i = 0; i < depth; ++i)
391 std::cerr << pfx << (static_cast<Node*>(n)->item) << std::endl;
394 res = res & rec_dump(n->next<A>(Dir::L), depth + 1, dpx, print, '\\');
396 int b = dpx[1] - dpx[0];
403 Bal x = n->balance();
404 if ((b < -1 || b > 1) ||
405 (b == 0 && x != Bal::N) ||
406 (b == -1 && x != Bal::L) ||
407 (b == 1 && x != Bal::R))
410 fprintf(stderr, "%2d: [%8p] b=%1d: balance error %d\n", depth, n, (int)n->balance().d, b);