6 # include <ahFunction.H>
7 # include <tpl_arrayStack.H>
9 # include <tpl_binNodeUtils.H>
11 using namespace Aleph;
34 template <
template <
typename>
class NodeType,
typename Key,
class Compare>
39 typedef NodeType<Key> Node;
49 bool avl_stack_empty() {
return avl_stack.
top() == head_ptr; }
51 void clean_avl_stack() { avl_stack.
popn (avl_stack.
size() - 1); }
53 Node * search_and_stack_avl(
const Key & key)
63 else if (cmp(
KEY(p), key))
68 while (p != Node::NullPtr);
70 return avl_stack.
top();
73 Node * search_dup_and_stack_avl(
const Key & key)
86 while (p != Node::NullPtr);
88 return avl_stack.
top();
91 static Node * rotateLeft(Node * p)
94 I(
RLINK(p) != Node::NullPtr);
106 DIFF(q) = DIFF(p) = 0;
111 static Node * rotateRight(Node * p)
114 I(
LLINK(p) != Node::NullPtr);
126 DIFF(q) = DIFF(p) = 0;
131 static Node * doubleRotateLeft(Node * p)
133 I(DIFF(p) == 2 or DIFF(p) == -2);
152 else if (DIFF(r) == -1)
168 static Node * doubleRotateRight(Node * p)
170 I(DIFF(p) == 2 or DIFF(p) == -2);
189 else if (DIFF(r) == -1)
206 { ROTATE_LEFT, ROTATE_RIGHT, DOUBLE_ROTATE_LEFT, DOUBLE_ROTATE_RIGHT };
208 static Rotation_Type rotation_type(Node * p)
210 I(DIFF(p) == 2 or DIFF(p) == -2);
216 if (DIFF(pc) == 1 or DIFF(pc) == 0)
219 return DOUBLE_ROTATE_LEFT;
223 if (DIFF(pc) == -1 or DIFF(pc) == 0)
226 return DOUBLE_ROTATE_RIGHT;
229 static Node * restore_avl(Node * p, Node * pp)
232 I(DIFF(p) == -2 or DIFF(p) == 2);
235 switch (rotation_type(p))
237 case ROTATE_LEFT:
return *link = rotateLeft(p);
238 case ROTATE_RIGHT:
return *link = rotateRight(p);
239 case DOUBLE_ROTATE_LEFT:
return *link = doubleRotateLeft(p);
240 case DOUBLE_ROTATE_RIGHT:
return *link = doubleRotateRight(p);
243 ERROR(
"Invalid rotation type");
250 void restore_avl_after_insertion(Node * p)
252 Node * pp = avl_stack.
pop();
264 if (avl_stack_empty())
270 gpp = avl_stack.
pop();
272 if (
LLINK(gpp) == pp)
279 else if (DIFF(gpp) == -2 or DIFF(gpp) == 2)
281 Node *ggpp = avl_stack.
pop();
282 restore_avl(gpp, ggpp);
288 while (not avl_stack_empty());
293 Node * swapWithSuccessor(Node * p, Node *& pp)
296 Node *& ref_to_stack_top = avl_stack.
top();
299 Node *succ =
RLINK(p);
301 avl_stack.
push(succ);
304 while (
LLINK(succ) != Node::NullPtr)
308 avl_stack.
push(succ);
313 ref_to_stack_top = succ;
321 LLINK(p) = Node::NullPtr;
322 if (
RLINK(p) == succ)
330 Node *succr =
RLINK(succ);
337 DIFF(succ) = DIFF(p);
342 void restore_avl_after_deletion(
bool left_deficit)
344 Node * pp = avl_stack.
top(1);
345 Node * ppp = avl_stack.
popn(3);
353 if (DIFF(pp) == -2 or DIFF(pp) == 2)
354 pp = restore_avl(pp, ppp);
356 if (DIFF(pp) != 0 or pp == root)
359 left_deficit =
LLINK(ppp) == pp;
361 ppp = avl_stack.
pop();
380 : avl_stack(
Node::MaxHeight), head_ptr(&head_node),
381 root(
RLINK (head_ptr)), cmp(__cmp)
383 avl_stack.
push(head_ptr);
387 : avl_stack(Node::MaxHeight), head_ptr(&head_node),
388 root(
RLINK (head_ptr)), cmp(__cmp)
390 avl_stack.
push(head_ptr);
400 std::swap(root, tree.root);
401 std::swap(cmp, tree.cmp);
414 return searchInBinTree <Node, Compare> (root, key, cmp);
422 if (root == Node::NullPtr)
425 Node *pp = search_and_stack_avl(
KEY(p));
426 if (cmp (
KEY(p),
KEY(pp)))
428 else if (cmp (
KEY(pp),
KEY(p)))
436 restore_avl_after_insertion(p);
457 if (root == Node::NullPtr)
460 Node *pp = search_and_stack_avl(
KEY(p));
461 if (cmp (
KEY(p),
KEY(pp)))
463 else if (cmp (
KEY(pp),
KEY(p)))
471 restore_avl_after_insertion(p);
480 if (root == Node::NullPtr)
483 Node *pp = search_dup_and_stack_avl(
KEY(p));
484 if (cmp (
KEY(p),
KEY(pp)))
489 restore_avl_after_insertion(p);
499 if (root == Node::NullPtr)
502 Node * p = search_and_stack_avl(key);
503 if (no_equals<Key, Compare> (
KEY(p), key, cmp))
513 left_deficit =
LLINK(pp) == p;
514 if (
LLINK(p) == Node::NullPtr)
523 if (
RLINK(p) == Node::NullPtr)
533 swapWithSuccessor(p, pp);
545 restore_avl_after_deletion(left_deficit);
572 template <
typename Key,
class Compare = Aleph::less<Key>>
577 Avl_Tree(Compare && cmp = Compare())
606 template <
typename Key,
class Compare = Aleph::less<Key>>
#define LLINK(p)
Definition: tpl_binNode.H:196
Node * search(const Key &key) const
Definition: tpl_avl.H:412
#define RLINK(p)
Definition: tpl_binNode.H:201
Node * insert(Node *p)
Definition: tpl_avl.H:420
virtual ~Gen_Avl_Tree()
Destruye un árbol AVL genérico.
Definition: tpl_avl.H:405
T pop()
Definition: tpl_arrayStack.H:353
Compare & key_comp()
Retorna una referencia al criterio de comparación.
Definition: tpl_avl.H:373
T & push(const T &data)
Definition: tpl_arrayStack.H:312
const size_t & size() const
Retorna el número de elementos que contiene la pila.
Definition: tpl_arrayStack.H:419
T popn(const int &n)
Definition: tpl_arrayStack.H:369
Node * insert_dup(Node *p)
Definition: tpl_avl.H:478
Definition: tpl_avl.H:607
Node *& getRoot()
Obtiene un puntero a la raíz del árbol.
Definition: tpl_avl.H:408
Key key_type
El tipo de clave que contiene el nodo.
Definition: tpl_avl.H:370
Node * search_or_insert(Node *p)
Definition: tpl_avl.H:455
void swap(Gen_Avl_Tree &tree)
Definition: tpl_avl.H:398
Gen_Avl_Tree(Compare &&__cmp)
Instancia un árbol AVL genérico.
Definition: tpl_avl.H:379
Definition: tpl_avl.H:573
T & top()
retorna una referencia al elemento situado en el tope de la pila.
Definition: tpl_arrayStack.H:378
#define KEY(p)
Definition: tpl_binNode.H:206
Compare & get_compare()
Definition: tpl_avl.H:376