MPogoda

avl

May 3rd, 2011
259
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 12.57 KB | None | 0 0
  1. /*
  2.  * avltree - Implements an AVL tree with parent pointers.
  3.  *
  4.  * Copyright (C) 2010 Franck Bui-Huu <[email protected]>
  5.  *
  6.  * This library is free software; you can redistribute it and/or
  7.  * modify it under the terms of the GNU Lesser General Public License
  8.  * as published by the Free Software Foundation; version 2 of the
  9.  * License.
  10.  *
  11.  * This library is distributed in the hope that it will be useful, but
  12.  * WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14.  * Lesser General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU Lesser General Public
  17.  * License along with this library; if not, write to the Free Software
  18.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
  19.  * USA
  20.  */
  21. #include <assert.h>
  22.  
  23. #include "libtree.h"
  24.  
  25.  
  26. #ifndef UINTPTR_MAX
  27.  
  28. static inline int is_root(struct avltree_node *node)
  29. {
  30.     return node->parent == NULL;
  31. }
  32.  
  33. static inline void INIT_NODE(struct avltree_node *node)
  34. {
  35.     node->left = NULL;
  36.     node->right = NULL;
  37.     node->parent = NULL;
  38.     node->balance = 0;
  39. }
  40.  
  41. static inline signed get_balance(struct avltree_node *node)
  42. {
  43.     return node->balance;
  44. }
  45.  
  46. static inline void set_balance(int balance, struct avltree_node *node)
  47. {
  48.     node->balance = balance;
  49. }
  50.  
  51. static inline int inc_balance(struct avltree_node *node)
  52. {
  53.     return ++node->balance;
  54. }
  55.  
  56. static inline int dec_balance(struct avltree_node *node)
  57. {
  58.     return --node->balance;
  59. }
  60.  
  61. static inline struct avltree_node *get_parent(const struct avltree_node *node)
  62. {
  63.     return node->parent;
  64. }
  65.  
  66. static inline void set_parent(struct avltree_node *parent,
  67.                   struct avltree_node *node)
  68. {
  69.     node->parent = parent;
  70. }
  71.  
  72. #else
  73.  
  74. static inline int is_root(struct avltree_node *node)
  75. {
  76.     return !(node->parent & ~7UL);
  77. }
  78.  
  79. static inline void INIT_NODE(struct avltree_node *node)
  80. {
  81.     node->left = NULL;
  82.     node->right = NULL;
  83.     node->parent = 2;
  84. }
  85.  
  86. static inline signed get_balance(struct avltree_node *node)
  87. {
  88.     return (int)(node->parent & 7) - 2;
  89. }
  90.  
  91. static inline void set_balance(int balance, struct avltree_node *node)
  92. {
  93.     node->parent = (node->parent & ~7UL) | (balance + 2);
  94. }
  95.  
  96. static inline int inc_balance(struct avltree_node *node)
  97. {
  98.     return (int)(++node->parent & 7) - 2;
  99. }
  100.  
  101. static inline int dec_balance(struct avltree_node *node)
  102. {
  103.     return (int)(--node->parent & 7) - 2;
  104. }
  105.  
  106. static inline struct avltree_node *get_parent(const struct avltree_node *node)
  107. {
  108.     return (struct avltree_node *)(node->parent & ~7UL);
  109. }
  110.  
  111. static inline void set_parent(const struct avltree_node *parent,
  112.                   struct avltree_node *node)
  113. {
  114.     node->parent = (uintptr_t)parent | (node->parent & 7);
  115. }
  116.  
  117. #endif
  118.  
  119. /*
  120.  * Iterators
  121.  */
  122. static inline struct avltree_node *get_first(struct avltree_node *node)
  123. {
  124.     while (node->left)
  125.         node = node->left;
  126.     return node;
  127. }
  128.  
  129. static inline struct avltree_node *get_last(struct avltree_node *node)
  130. {
  131.     while (node->right)
  132.         node = node->right;
  133.     return node;
  134. }
  135.  
  136. struct avltree_node *avltree_first(const struct avltree *tree)
  137. {
  138.     return tree->first;
  139. }
  140.  
  141. struct avltree_node *avltree_last(const struct avltree *tree)
  142. {
  143.     return tree->last;
  144. }
  145.  
  146. struct avltree_node *avltree_next(const struct avltree_node *node)
  147. {
  148.     struct avltree_node *parent;
  149.  
  150.     if (node->right)
  151.         return get_first(node->right);
  152.  
  153.     while ((parent = get_parent(node)) && parent->right == node)
  154.         node = parent;
  155.     return parent;
  156. }
  157.  
  158. struct avltree_node *avltree_prev(const struct avltree_node *node)
  159. {
  160.     struct avltree_node *parent;
  161.  
  162.     if (node->left)
  163.         return get_last(node->left);
  164.  
  165.     while ((parent = get_parent(node)) && parent->left == node)
  166.         node = parent;
  167.     return parent;
  168. }
  169.  
  170.  
  171. /*
  172.  * The AVL tree is more rigidly balanced than Red-Black trees, leading
  173.  * to slower insertion and removal but faster retrieval.
  174.  */
  175.  
  176. /* node->balance = height(node->right) - height(node->left); */
  177. static void rotate_left(struct avltree_node *node, struct avltree *tree)
  178. {
  179.     struct avltree_node *p = node;
  180.     struct avltree_node *q = node->right; /* can't be NULL */
  181.     struct avltree_node *parent = get_parent(p);
  182.  
  183.     if (!is_root(p)) {
  184.         if (parent->left == p)
  185.             parent->left = q;
  186.         else
  187.             parent->right = q;
  188.     } else
  189.         tree->root = q;
  190.     set_parent(parent, q);
  191.     set_parent(q, p);
  192.  
  193.     p->right = q->left;
  194.     if (p->right)
  195.         set_parent(p, p->right);
  196.     q->left = p;
  197. }
  198.  
  199. static void rotate_right(struct avltree_node *node, struct avltree *tree)
  200. {
  201.     struct avltree_node *p = node;
  202.     struct avltree_node *q = node->left; /* can't be NULL */
  203.     struct avltree_node *parent = get_parent(p);
  204.  
  205.     if (!is_root(p)) {
  206.         if (parent->left == p)
  207.             parent->left = q;
  208.         else
  209.             parent->right = q;
  210.     } else
  211.         tree->root = q;
  212.     set_parent(parent, q);
  213.     set_parent(q, p);
  214.  
  215.     p->left = q->right;
  216.     if (p->left)
  217.         set_parent(p, p->left);
  218.     q->right = p;
  219. }
  220.  
  221. /*
  222.  * 'pparent', 'unbalanced' and 'is_left' are only used for
  223.  * insertions. Normally GCC will notice this and get rid of them for
  224.  * lookups.
  225.  */
  226. static inline struct avltree_node *do_lookup(const struct avltree_node *key,
  227.                          const struct avltree *tree,
  228.                          struct avltree_node **pparent,
  229.                          struct avltree_node **unbalanced,
  230.                          int *is_left)
  231. {
  232.     struct avltree_node *node = tree->root;
  233.     int res = 0;
  234.  
  235.     *pparent = NULL;
  236.     *unbalanced = node;
  237.     *is_left = 0;
  238.  
  239.     while (node) {
  240.         if (get_balance(node) != 0)
  241.             *unbalanced = node;
  242.  
  243.         res = tree->cmp_fn(node, key);
  244.         if (res == 0)
  245.             return node;
  246.         *pparent = node;
  247.         if ((*is_left = res > 0))
  248.             node = node->left;
  249.         else
  250.             node = node->right;
  251.     }
  252.     return NULL;
  253. }
  254.  
  255. struct avltree_node *avltree_lookup(const struct avltree_node *key,
  256.                     const struct avltree *tree)
  257. {
  258.     struct avltree_node *parent, *unbalanced;
  259.     int is_left;
  260.  
  261.     return do_lookup(key, tree, &parent, &unbalanced, &is_left);
  262. }
  263.  
  264. static void set_child(struct avltree_node *child,
  265.               struct avltree_node *node, int left)
  266. {
  267.     if (left)
  268.         node->left = child;
  269.     else
  270.         node->right = child;
  271. }
  272.  
  273. /* Insertion never needs more than 2 rotations */
  274. struct avltree_node *avltree_insert(struct avltree_node *node, struct avltree *tree)
  275. {
  276.     struct avltree_node *key, *parent, *unbalanced;
  277.     int is_left;
  278.  
  279.     key = do_lookup(node, tree, &parent, &unbalanced, &is_left);
  280.     if (key)
  281.         return key;
  282.  
  283.     INIT_NODE(node);
  284.  
  285.     if (!parent) {
  286.         tree->root = node;
  287.         tree->first = tree->last = node;
  288.         tree->height++;
  289.         return NULL;
  290.     }
  291.     if (is_left) {
  292.         if (parent == tree->first)
  293.             tree->first = node;
  294.     } else {
  295.         if (parent == tree->last)
  296.             tree->last = node;
  297.     }
  298.     set_parent(parent, node);
  299.     set_child(node, parent, is_left);
  300.  
  301.     for (;;) {
  302.         if (parent->left == node)
  303.             dec_balance(parent);
  304.         else
  305.             inc_balance(parent);
  306.  
  307.         if (parent == unbalanced)
  308.             break;
  309.         node = parent;
  310.         parent = get_parent(parent);
  311.     }
  312.  
  313.     switch (get_balance(unbalanced)) {
  314.     case  1: case -1:
  315.         tree->height++;
  316.         /* fall through */
  317.     case 0:
  318.         break;
  319.     case 2: {
  320.         struct avltree_node *right = unbalanced->right;
  321.  
  322.         if (get_balance(right) == 1) {
  323.             set_balance(0, unbalanced);
  324.             set_balance(0, right);
  325.         } else {
  326.             switch (get_balance(right->left)) {
  327.             case 1:
  328.                 set_balance(-1, unbalanced);
  329.                 set_balance( 0, right);
  330.                 break;
  331.             case 0:
  332.                 set_balance(0, unbalanced);
  333.                 set_balance(0, right);
  334.                 break;
  335.             case -1:
  336.                 set_balance(0, unbalanced);
  337.                 set_balance(1, right);
  338.                 break;
  339.             }
  340.             set_balance(0, right->left);
  341.  
  342.             rotate_right(right, tree);
  343.         }
  344.         rotate_left(unbalanced, tree);
  345.         break;
  346.     }
  347.     case -2: {
  348.         struct avltree_node *left = unbalanced->left;
  349.  
  350.         if (get_balance(left) == -1) {
  351.             set_balance(0, unbalanced);
  352.             set_balance(0, left);
  353.         } else {
  354.             switch (get_balance(left->right)) {
  355.             case 1:
  356.                 set_balance( 0, unbalanced);
  357.                 set_balance(-1, left);
  358.                 break;
  359.             case 0:
  360.                 set_balance(0, unbalanced);
  361.                 set_balance(0, left);
  362.                 break;
  363.             case -1:
  364.                 set_balance(1, unbalanced);
  365.                 set_balance(0, left);
  366.                 break;
  367.             }
  368.             set_balance(0, left->right);
  369.  
  370.             rotate_left(left, tree);
  371.         }
  372.         rotate_right(unbalanced, tree);
  373.         break;
  374.     }
  375.     }
  376.     return NULL;
  377. }
  378.  
  379. /* Deletion might require up to log(n) rotations */
  380. void avltree_remove(struct avltree_node *node, struct avltree *tree)
  381. {
  382.     struct avltree_node *parent = get_parent(node);
  383.     struct avltree_node *left = node->left;
  384.     struct avltree_node *right = node->right;
  385.     struct avltree_node *next;
  386.     int is_left = is_left;
  387.  
  388.     if (node == tree->first)
  389.         tree->first = avltree_next(node);
  390.     if (node == tree->last)
  391.         tree->last = avltree_prev(node);
  392.  
  393.     if (!left)
  394.         next = right;
  395.     else if (!right)
  396.         next = left;
  397.     else
  398.         next = get_first(right);
  399.  
  400.     if (parent) {
  401.         is_left = parent->left == node;
  402.         set_child(next, parent, is_left);
  403.     } else
  404.         tree->root = next;
  405.  
  406.     if (left && right) {
  407.         set_balance(get_balance(node), next);
  408.  
  409.         next->left = left;
  410.         set_parent(next, left);
  411.  
  412.         if (next != right) {
  413.             parent = get_parent(next);
  414.             set_parent(get_parent(node), next);
  415.  
  416.             node = next->right;
  417.             parent->left = node;
  418.             is_left = 1;
  419.  
  420.             next->right = right;
  421.             set_parent(next, right);
  422.         } else {
  423.             set_parent(parent, next);
  424.             parent = next;
  425.             node = parent->right;
  426.             is_left = 0;
  427.         }
  428.         assert(parent != NULL);
  429.     } else
  430.         node = next;
  431.  
  432.     if (node)
  433.         set_parent(parent, node);
  434.  
  435.     /*
  436.      * At this point, 'parent' can only be null, if 'node' is the
  437.      * tree's root and has at most one child.
  438.      *
  439.      * case 1: the subtree is now balanced but its height has
  440.      * decreased.
  441.      *
  442.      * case 2: the subtree is mostly balanced and its height is
  443.      * unchanged.
  444.      *
  445.      * case 3: the subtree is unbalanced and its height may have
  446.      * been changed during the rebalancing process, see below.
  447.      *
  448.      * case 3.1: after a left rotation, the subtree becomes mostly
  449.      * balanced and its height is unchanged.
  450.      *
  451.      * case 3.2: after a left rotation, the subtree becomes
  452.      * balanced but its height has decreased.
  453.      *
  454.      * case 3.3: after a left and a right rotation, the subtree
  455.      * becomes balanced or mostly balanced but its height has
  456.      * decreased for all cases.
  457.      */
  458.     while (parent) {
  459.         int balance;
  460.         node   = parent;
  461.         parent = get_parent(parent);
  462.  
  463.         if (is_left) {
  464.             is_left = parent && parent->left == node;
  465.  
  466.             balance = inc_balance(node);
  467.             if (balance == 0)       /* case 1 */
  468.                 continue;
  469.             if (balance == 1)       /* case 2 */
  470.                 return;
  471.             right = node->right;        /* case 3 */
  472.             switch (get_balance(right)) {
  473.             case 0:             /* case 3.1 */
  474.                 set_balance( 1, node);
  475.                 set_balance(-1, right);
  476.                 rotate_left(node, tree);
  477.                 return;
  478.             case 1:             /* case 3.2 */
  479.                 set_balance(0, node);
  480.                 set_balance(0, right);
  481.                 break;
  482.             case -1:            /* case 3.3 */
  483.                 switch (get_balance(right->left)) {
  484.                 case 1:
  485.                     set_balance(-1, node);
  486.                     set_balance( 0, right);
  487.                     break;
  488.                 case 0:
  489.                     set_balance(0, node);
  490.                     set_balance(0, right);
  491.                     break;
  492.                 case -1:
  493.                     set_balance(0, node);
  494.                     set_balance(1, right);
  495.                     break;
  496.                 }
  497.                 set_balance(0, right->left);
  498.  
  499.                 rotate_right(right, tree);
  500.             }
  501.             rotate_left(node, tree);
  502.         } else {
  503.             is_left = parent && parent->left == node;
  504.  
  505.             balance = dec_balance(node);
  506.             if (balance == 0)
  507.                 continue;
  508.             if (balance == -1)
  509.                 return;
  510.             left = node->left;
  511.             switch (get_balance(left)) {
  512.             case 0:
  513.                 set_balance(-1, node);
  514.                 set_balance(1, left);
  515.                 rotate_right(node, tree);
  516.                 return;
  517.             case -1:
  518.                 set_balance(0, node);
  519.                 set_balance(0, left);
  520.                 break;
  521.             case 1:
  522.                 switch (get_balance(left->right)) {
  523.                 case 1:
  524.                     set_balance(0, node);
  525.                     set_balance(-1, left);
  526.                     break;
  527.                 case 0:
  528.                     set_balance(0, node);
  529.                     set_balance(0, left);
  530.                     break;
  531.                 case -1:
  532.                     set_balance(1, node);
  533.                     set_balance(0, left);
  534.                     break;
  535.                 }
  536.                 set_balance(0, left->right);
  537.  
  538.                 rotate_left(left, tree);
  539.             }
  540.             rotate_right(node, tree);
  541.         }
  542.     }
  543.     tree->height--;
  544. }
  545.  
  546. void avltree_replace(struct avltree_node *old, struct avltree_node *new,
  547.              struct avltree *tree)
  548. {
  549.     struct avltree_node *parent = get_parent(old);
  550.  
  551.     if (parent)
  552.         set_child(parent, new, parent->left == old);
  553.     else
  554.         tree->root = new;
  555.  
  556.     if (old->left)
  557.         set_parent(new, old->left);
  558.     if (old->right)
  559.         set_parent(new, old->right);
  560.  
  561.     if (tree->first == old)
  562.         tree->first = new;
  563.     if (tree->last == old)
  564.         tree->last = new;
  565.  
  566.     *new = *old;
  567. }
  568.  
  569. int avltree_init(struct avltree *tree, avltree_cmp_fn_t cmp, unsigned long flags)
  570. {
  571.     if (flags)
  572.         return -1;
  573.     tree->root = NULL;
  574.     tree->cmp_fn = cmp;
  575.     tree->height = -1;
  576.     tree->first = NULL;
  577.     tree->last = NULL;
  578.     return 0;
  579. }
Advertisement
Add Comment
Please, Sign In to add comment