31 friend struct ::Avl_set_tester;
34 template<
typename Node,
typename Get_key,
typename Compare >
72 bool balanced()
const {
return _balance ==
Bal::N; }
75 Bal balance()
const {
return _balance; }
78 void balance(Bal b) { _balance = b; }
98template<
typename Node,
typename Get_key,
99 typename Compare = Lt_functor<typename Get_key::Key_type> >
170 bool rec_dump(
Avl_tree_node *n,
int depth,
int *dp,
bool print,
char pfx);
171 bool rec_dump(
bool print)
174 return rec_dump(
static_cast<Avl_tree_node *
>(_head), 0, &dp, print,
'+');
186Avl_tree_node::rotate2(Bst_node **t, Bal idir, Bal pre)
188 typedef Bits::Bst_node N;
190 N *tmp[2] = { *t, N::next(*t, idir) };
191 *t = N::next(tmp[1], !idir);
192 A *n =
static_cast<A*
>(*t);
194 N::next(tmp[0], idir, N::next(n, !idir));
195 N::next(tmp[1], !idir, N::next(n, idir));
196 N::next(n, !idir, tmp[0]);
197 N::next(n, idir, tmp[1]);
203 static_cast<A*
>(tmp[0])->balance(
Bal::N);
204 static_cast<A*
>(tmp[1])->balance(
Bal::N);
208 static_cast<A*
>(tmp[pre != idir])->balance(!pre);
209 static_cast<A*
>(tmp[pre == idir])->balance(
Bal::N);
211 return N::next(tmp[pre == idir], !pre);
218template<
typename Node,
typename Get_key,
class Compare>
226 Key_param_type new_key = Get_key::key_of(new_node);
229 for (N *p; (p = *t);)
231 Dir b = this->dir(new_key, p);
233 return pair(
static_cast<Node*
>(p),
false);
235 if (!
static_cast<A
const *
>(p)->balanced())
241 *
static_cast<A*
>(new_node) = A(
true);
245 A *a =
static_cast<A*
>(n);
248 A::Bal b(this->greater(new_key, n));
249 if (a->balance() != b)
256 else if (b ==
Bal(this->greater(new_key, A::next(n, b))))
261 static_cast<A*
>(*s)->balance(Bal::N);
267 n = A::next(A::next(n, b), !b);
268 n = A::rotate2(s, b, n == new_node ? Bal::N :
Bal(this->greater(new_key, n)));
272 for (A::Bal b; n && n != new_node;
static_cast<A*
>(n)->balance(b), n = A::next(n, b))
273 b =
Bal(this->greater(new_key, n));
275 return pair(new_node,
true);
280template<
typename Node,
typename Get_key,
class Compare>
294 for (N *n; (n = *q); q = A::next_p(n, dir))
296 dir =
Dir(this->greater(key, n));
297 if (dir == Dir::L && !this->greater(k(n), key))
301 if (!A::next(n, dir))
304 A
const *a =
static_cast<A
const *
>(n);
305 if (a->balanced() || (a->balance() == !dir && A::next<A>(n, !dir)->balanced()))
313 A *i =
static_cast<A*
>(*t);
315 for (N *n; (n = *s); s = A::next_p(n, dir))
317 dir =
Dir(this->greater(key, n));
319 if (!A::next(n, dir))
322 A *a =
static_cast<A*
>(n);
326 else if (a->balance() == dir)
331 Bal b = A::next<A>(n, !dir)->balance();
333 A::rotate2(s, !dir, A::next<A>(A::next(n, !dir), dir)->balance());
340 static_cast<A*
>(*s)->balance(Bal::N);
345 static_cast<A*
>(*s)->balance(dir);
349 t = A::next_p(*s, dir);
353 A *n =
static_cast<A*
>(*q);
355 *q = A::next(n, !dir);
358 return static_cast<Node*
>(i);
362template<
typename Node,
typename Get_key,
class Compare>
370 int dpx[2] = {depth,depth};
373 res = rec_dump(A::next<A>(n, Dir::R), depth + 1, dpx + 1, print,
'/');
377 fprintf(stderr,
"%2d: [%8p] b=%1d: ", depth, n, (
int)n->balance().d);
379 for (
int i = 0; i < depth; ++i)
382 std::cerr << pfx << (static_cast<Node*>(n)->item) << std::endl;
385 res = res & rec_dump(A::next<A>(n, Dir::L), depth + 1, dpx, print,
'\\');
387 int b = dpx[1] - dpx[0];
394 Bal x = n->balance();
395 if ((b < -1 || b > 1) ||
396 (b == 0 && x != Bal::N) ||
397 (b == -1 && x != Bal::L) ||
398 (b == 1 && x != Bal::R))
401 fprintf(stderr,
"%2d: [%8p] b=%1d: balance error %d\n", depth, n, (
int)n->balance().d, b);
Avl_tree_node()=default
Create an uninitialized node, this is what you should do.
Pair< Node *, bool > insert(Node *new_node)
Insert a new node into this AVL tree.
Node * erase(Key_param_type key)
An alias for remove().
Node * remove(Key_param_type key)
Remove the node with key from the tree.
~Avl_tree() noexcept
Destroy the tree.
Avl_tree()=default
Create an empty AVL tree.
Bst::Const_iterator Const_iterator
Constant forward iterator for the tree.
Bst::Rev_iterator Rev_iterator
Backward iterator for the tree.
Bst::Const_rev_iterator Const_rev_iterator
Constant backward iterator for the tree.
Basic type of a node in a binary search tree (BST).
static Bst_node ** next_p(Bst_node *p, Direction d)
Get pointer to link in direction d.
static void rotate(Bst_node **t, Direction idir)
Rotate subtree t in the opposite direction of idir.
Bst_node()
Create uninitialized node.
static Bst_node * next(Bst_node const *p, Direction d)
Get next node in direction d.
Basic binary search tree (BST).
__Bst_iter< Node, Node const, Rev > Const_rev_iterator
Constant backward.
Get_key::Key_type Key_type
The type of key values used to generate the total order of the elements.
__Bst_iter< Node, Node, Fwd > Iterator
Forward iterator.
Type_traits< Key_type >::Param_type Key_param_type
The type for key parameters.
Bst_node * _head
The head pointer of the tree.
__Bst_iter< Node, Node const, Fwd > Const_iterator
Constant forward iterator.
void remove_all(FUNC &&callback)
Clear the tree.
static Key_type k(Bst_node const *n)
Get the key value of n.
__Bst_iter< Node, Node, Rev > Rev_iterator
Backward iterator.
The direction to go in a binary search tree.