123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592 |
- #include "avltree.h"
- #include <stdint.h>
- #include <stdio.h>
- // #define AVL_DEBUG
- #ifdef AVL_DEBUG
- #define avl_debug(...) printf(__VA_ARGS__)
- #else
- #define avl_debug(...)
- #endif
- static void __avl_rotate_right(struct avl_node *node, struct avl_root *root);
- static void __avl_rotate_left(struct avl_node *node, struct avl_root *root);
- static int __avl_balance_right(struct avl_node *node, struct avl_root *root);
- static int __avl_balance_left(struct avl_node *node, struct avl_root *root);
- static int __left_hand_insert_track_back(struct avl_node *node, struct avl_root *root);
- static int __right_hand_insert_track_back(struct avl_node *node, struct avl_root *root);
- #define __left_hand_delete_track_back(node, root) __right_hand_insert_track_back(node, root)
- #define __right_hand_delete_track_back(node, root) __left_hand_insert_track_back(node, root)
- /**
- * @brief __avl_rotate_right
- * 对 node 节点进行单右旋处理
- * @param node 二叉树节点
- * @param root 二叉树根
- * @return
- */
- static void __avl_rotate_right(struct avl_node *node, struct avl_root *root)
- {
- // 对以*node为根的二叉树作右旋转处理,处理之后node指向新的树根结点
- // 即旋转处理之前的左子树的根结点
- struct avl_node *left = node->avl_left;
- struct avl_node *parent = avl_parent(node);
- if ((node->avl_left = left->avl_right))
- avl_set_parent(left->avl_right, node);
- left->avl_right = node;
- avl_set_parent(left, parent);
- if (parent)
- {
- if (node == parent->avl_right)
- parent->avl_right = left;
- else
- parent->avl_left = left;
- }
- else
- root->avl_node = left;
- avl_set_parent(node, left);
- }
- /**
- * @brief __avl_rotate_left
- * 对 node 节点进行单左旋处理
- * @param node 二叉树节点
- * @param root 二叉树根
- * @return
- */
- static void __avl_rotate_left(struct avl_node *node, struct avl_root *root)
- {
- struct avl_node *right = node->avl_right;
- struct avl_node *parent = avl_parent(node);
- if ((node->avl_right = right->avl_left))
- avl_set_parent(right->avl_left, node);
- right->avl_left = node;
- avl_set_parent(right, parent);
- if (parent)
- {
- if (node == parent->avl_left)
- parent->avl_left = right;
- else
- parent->avl_right = right;
- }
- else
- root->avl_node = right;
- avl_set_parent(node, right);
- }
- /**
- * @brief __avl_balance_left
- * 当 node 节点左子树高于右子树, 对 node 节点进行左平衡处理并更新平衡因子
- * @param node 二叉树节点
- * @param root 二叉树根
- * @return 对于原 node 所在位置,经过平衡处理使树的高度降低了返回 -1,否则返回0
- */
- static int __avl_balance_left(struct avl_node *node, struct avl_root *root)
- {
- int retl = 0;
- int left_right_child_scale;
- struct avl_node *left_child = node->avl_left;
- struct avl_node *left_left_child;
- struct avl_node *left_right_child;
- if (left_child)
- {
- left_left_child = left_child->avl_left;
- left_right_child = left_child->avl_right;
- switch (avl_scale(left_child))
- {
- case AVL_BALANCED: // 只有在删除的时候会出现这种情况,情况非常复杂,需小心处理
- left_right_child_scale = avl_scale(left_right_child);
- __avl_rotate_left(node->avl_left, root); // 对*node的左子树作左平衡处理
- __avl_rotate_right(node, root); // 对*node作右平衡处理
- avl_set_tilt_left(left_child);
- avl_set_tilt_left(left_right_child);
- if (left_right_child_scale == AVL_BALANCED)
- avl_set_balanced(node);
- else if (left_right_child_scale == AVL_TILT_LEFT)
- avl_set_tilt_right(node);
- else
- {
- int left_left_child_scale = avl_scale(left_left_child);
- avl_set_balanced(node);
- retl = __avl_balance_left(left_child, root); // 这种情况需递归,并需要根据递归结果更新平衡因子
- if ((retl < 0) || (left_left_child_scale != AVL_BALANCED))
- avl_set_balanced(left_right_child);
- }
- avl_debug("L_R\r\n");
- break;
- case AVL_TILT_LEFT:
- __avl_rotate_right(node, root);
- avl_set_balanced(node);
- avl_set_balanced(left_child);
- retl = -1; // 高度变低了
- avl_debug("R\r\n");
- break;
- case AVL_TILT_RIGHT:
- __avl_rotate_left(node->avl_left, root); // 对*node的左子树作左平衡处理
- __avl_rotate_right(node, root); // 对*node作右平衡处理
- switch (avl_scale(left_right_child))
- {
- case AVL_BALANCED:
- avl_set_balanced(node);
- avl_set_balanced(left_child);
- break;
- case AVL_TILT_RIGHT:
- avl_set_balanced(node);
- avl_set_tilt_left(left_child);
- break;
- case AVL_TILT_LEFT:
- avl_set_balanced(left_child);
- avl_set_tilt_right(node);
- break;
- }
- avl_set_balanced(left_right_child);
- retl = -1; // 高度变低
- avl_debug("L_R\r\n");
- break;
- }
- }
- return retl;
- }
- /**
- * @brief __avl_balance_right
- * 当 node 节点右子树高于左子树, 对 node 节点进行左平衡处理并更新平衡因子
- * @param node 二叉树节点
- * @param root 二叉树根
- * @return 对于原 node 所在树的位置,经过平衡处理使树的高度降低了返回 -1,否则返回0
- */
- static int __avl_balance_right(struct avl_node *node, struct avl_root *root)
- {
- int ret = 0;
- int right_left_child_scale;
- struct avl_node *right_child = node->avl_right;
- struct avl_node *right_left_child = right_child->avl_left;
- struct avl_node *right_right_child = right_child->avl_right;
- if (right_child)
- {
- switch (avl_scale(right_child))
- {
- case AVL_BALANCED: // 删除的时候会出现这种情况,需要特别注意
- right_left_child_scale = avl_scale(right_left_child);
- __avl_rotate_right(node->avl_right, root);
- __avl_rotate_left(node, root);
- avl_set_tilt_right(right_left_child);
- avl_set_tilt_right(right_child);
- if (right_left_child_scale == AVL_BALANCED)
- avl_set_balanced(node);
- else if (right_left_child_scale == AVL_TILT_RIGHT)
- avl_set_tilt_left(node);
- else
- {
- int right_right_child_scale = avl_scale(right_right_child);
- avl_set_balanced(node);
- ret = __avl_balance_right(right_child, root); // 需递归一次
- if ((ret < 0) || (right_right_child_scale != AVL_BALANCED))
- avl_set_balanced(right_left_child);
- }
- avl_debug("R_L\r\n");
- break;
- case AVL_TILT_RIGHT:
- avl_debug("L\r\n");
- __avl_rotate_left(node, root);
- avl_set_balanced(node);
- avl_set_balanced(right_child);
- ret = -1; // 高度变低了//
- break;
- case AVL_TILT_LEFT:
- __avl_rotate_right(node->avl_right, root);
- __avl_rotate_left(node, root);
- avl_debug("R_L\r\n");
- switch (avl_scale(right_left_child)) // 旋转后要更新平衡因子
- {
- case AVL_TILT_LEFT:
- avl_set_tilt_right(right_child);
- avl_set_balanced(node);
- break;
- case AVL_BALANCED:
- avl_set_balanced(node);
- avl_set_balanced(right_child);
- break;
- case AVL_TILT_RIGHT:
- avl_set_balanced(right_child);
- avl_set_tilt_left(node);
- break;
- }
- avl_set_balanced(right_left_child);
- ret = -1; //
- break;
- }
- }
- return ret;
- }
- /**
- * @brief __left_hand_insert_track_back
- * 在 node 节点的左子树进行了插入,更新平衡因子,如失衡则作平衡处理
- * @param node 二叉树节点
- * @param root 二叉树根
- * @return 对于原 node 所在树的位置,经过平衡处理使树的高度降低了返回 -1,否则返回0
- */
- static int __left_hand_insert_track_back(struct avl_node *node, struct avl_root *root)
- {
- switch (avl_scale(node))
- {
- case AVL_BALANCED:
- avl_set_tilt_left(node);
- return 0;
- case AVL_TILT_RIGHT:
- avl_set_balanced(node);
- return -1;
- case AVL_TILT_LEFT:
- return __avl_balance_left(node, root);
- }
- return 0;
- }
- /**
- * @brief __left_hand_insert_track_back
- * 在 node 节点的右子树进行了插入,更新平衡因子,如失衡则作平衡处理
- * @param node 二叉树节点
- * @param root 二叉树根
- * @return 对于原 node 所在树的位置,插入并平衡后高度降低了返回 -1,否则返回0
- */
- static int __right_hand_insert_track_back(struct avl_node *node, struct avl_root *root)
- {
- switch (avl_scale(node))
- {
- case AVL_BALANCED:
- avl_set_tilt_right(node); // 父节点右倾
- return 0; // 以 node 为根的树高度被改变,但未失衡
- case AVL_TILT_LEFT:
- avl_set_balanced(node); // 父节点平衡
- return -1; // 以 node 为根的树高度不改变
- case AVL_TILT_RIGHT: // 以 node 为根的树已失衡,作平衡处理
- return __avl_balance_right(node, root); //
- }
- return 0;
- }
- void avl_insert(
- struct avl_root *root,
- struct avl_node *insertnode,
- struct avl_node *parent,
- struct avl_node **avl_link)
- {
- int taller = 1;
- struct avl_node *gparent = NULL;
- uint8_t parent_gparent_path = 0;
- uint8_t backtrack_path = 0;
- insertnode->avl_parent = (unsigned long)parent;
- insertnode->avl_left = insertnode->avl_right = NULL;
- *avl_link = insertnode;
- if (root->avl_node == insertnode)
- return;
- if (AVL_BALANCED != avl_scale(parent))
- {
- avl_set_balanced(parent); // 父节点平衡
- return; // 树没长高返回
- }
- backtrack_path = (insertnode == parent->avl_left) ? AVL_TILT_LEFT : AVL_TILT_RIGHT;
- // 树长高了,需要回溯平衡
- while (taller && parent)
- {
- // 回溯平衡过程会改变树的结构,先记录祖父节点和对应的回溯路径方向
- if ((gparent = avl_parent(parent))) // 先赋值再判断
- parent_gparent_path = (parent == gparent->avl_right) ? AVL_TILT_RIGHT : AVL_TILT_LEFT;
- if (backtrack_path == AVL_TILT_RIGHT)
- taller += __right_hand_insert_track_back(parent, root);
- else
- taller += __left_hand_insert_track_back(parent, root);
- backtrack_path = parent_gparent_path; // 回溯
- parent = gparent;
- }
- }
- #if 1
- void avl_delete(struct avl_root *root, struct avl_node *node)
- {
- struct avl_node *child, *parent;
- struct avl_node *gparent = NULL;
- int lower = 1;
- uint8_t parent_gparent_path = 0;
- uint8_t backtrack_path = 0;
- if (!node->avl_left) // 如果被删节点不存在左子树
- {
- child = node->avl_right; // 把右子树接入父节点中
- parent = avl_parent(node);
- if (child)
- avl_set_parent(child, parent);
- if (parent)
- {
- if (parent->avl_left == node)
- {
- parent->avl_left = child;
- backtrack_path = AVL_TILT_LEFT;
- }
- else
- {
- parent->avl_right = child;
- backtrack_path = AVL_TILT_RIGHT;
- }
- }
- else
- {
- root->avl_node = child;
- if (child)
- avl_set_balanced(child);
- return;
- }
- }
- else if (!node->avl_right) // 如果被删节点存在左子树,不存在右子树
- {
- child = node->avl_left;
- parent = avl_parent(node);
- avl_set_parent(child, parent);
- if (parent)
- {
- if (parent->avl_left == node)
- {
- parent->avl_left = child;
- backtrack_path = AVL_TILT_LEFT;
- }
- else
- {
- parent->avl_right = child;
- backtrack_path = AVL_TILT_RIGHT;
- }
- }
- else
- {
- root->avl_node = child;
- if (child)
- avl_set_balanced(child);
- return;
- }
- }
- else // 被删节点即存在左子树,也存在右子树
- {
- struct avl_node *old = node, *left;
- node = node->avl_right;
- while ((left = node->avl_left) != NULL)
- node = left; // 找到右子树下最小的替代点
- if (avl_parent(old)) // 旧点所在父节点
- {
- if (avl_parent(old)->avl_left == old)
- avl_parent(old)->avl_left = node;
- else
- avl_parent(old)->avl_right = node;
- }
- else
- root->avl_node = node;
- child = node->avl_right; // 最小的替代点的右节点
- parent = avl_parent(node); // 最小的替代点的父节点
- if (parent == old) // 要删除的节点的右子树没有左子树,替代点(1)没有右节点,(2)存在一个右节点
- {
- backtrack_path = AVL_TILT_RIGHT;
- parent = node;
- node->avl_parent = old->avl_parent;
- node->avl_left = old->avl_left;
- avl_set_parent(old->avl_left, node);
- }
- else // 要删除的节点的右子树有左子树
- {
- backtrack_path = AVL_TILT_LEFT;
- parent->avl_left = child; // 最小的替代点的右节点的父节点
- node->avl_right = old->avl_right;
- avl_set_parent(old->avl_right, node);
- node->avl_parent = old->avl_parent;
- node->avl_left = old->avl_left;
- avl_set_parent(old->avl_left, node);
- if (child)
- avl_set_parent(child, parent); // 要删除的节点的右子树的左子树末尾点存在右节点
- }
- }
- // 树低了,需要回溯平衡,直到回溯到根节点
- while (lower && parent)
- {
- if ((gparent = avl_parent(parent))) //(parent && (gparent = avl_parent(parent)))//先赋值再判断
- parent_gparent_path = (parent == gparent->avl_right) ? AVL_TILT_RIGHT : AVL_TILT_LEFT;
- if (backtrack_path == AVL_TILT_RIGHT) // 经过回溯调整会改变树的结构,所以先记录 gparent 和回溯路径
- lower = __right_hand_delete_track_back(parent, root);
- else
- lower = __left_hand_delete_track_back(parent, root);
- backtrack_path = parent_gparent_path;
- parent = gparent;
- }
- }
- #endif
- /*
- * This function returns the first node (in sort oright_left_childer) of the tree.
- */
- struct avl_node *avl_first(const struct avl_root *root)
- {
- struct avl_node *n;
- n = root->avl_node;
- if (!n)
- return NULL;
- while (n->avl_left)
- n = n->avl_left;
- return n;
- }
- struct avl_node *avl_last(const struct avl_root *root)
- {
- struct avl_node *n;
- n = root->avl_node;
- if (!n)
- return NULL;
- while (n->avl_right)
- n = n->avl_right;
- return n;
- }
- struct avl_node *avl_next(const struct avl_node *node)
- {
- struct avl_node *parent;
- if (avl_parent(node) == node)
- return NULL;
- /* If we have a right-hand child, go down and then left as far
- as we can. */
- if (node->avl_right)
- {
- node = node->avl_right;
- while (node->avl_left)
- node = node->avl_left;
- return (struct avl_node *)node;
- }
- /* No right-hand children. Everything down and left is
- smaller than us, so any 'next' node must be in the general
- direction of our parent. Go up the tree; any time the
- ancestor is a right-hand child of its parent, keep going
- up. First time it's a left-hand child of its parent, said
- parent is our 'next' node. */
- while ((parent = avl_parent(node)) && node == parent->avl_right)
- node = parent;
- return parent;
- }
- struct avl_node *avl_prev(const struct avl_node *node)
- {
- struct avl_node *parent;
- if (avl_parent(node) == node)
- return NULL;
- /* If we have a left-hand child, go down and then right as far
- as we can. */
- if (node->avl_left)
- {
- node = node->avl_left;
- while (node->avl_right)
- node = node->avl_right;
- return (struct avl_node *)node;
- }
- /* No left-hand children. Go up till we find an ancestor which
- is a right-hand child of its parent */
- while ((parent = avl_parent(node)) && node == parent->avl_left)
- node = parent;
- return parent;
- }
- void avl_replace_node(struct avl_node *victim, struct avl_node *new,
- struct avl_root *root)
- {
- struct avl_node *parent = avl_parent(victim);
- /* Set the surrounding nodes to point to the replacement */
- if (parent)
- {
- if (victim == parent->avl_left)
- parent->avl_left = new;
- else
- parent->avl_right = new;
- }
- else
- {
- root->avl_node = new;
- }
- if (victim->avl_left)
- avl_set_parent(victim->avl_left, new);
- if (victim->avl_right)
- avl_set_parent(victim->avl_right, new);
- /* Copy the pointers/colour from the victim to the replacement */
- *new = *victim;
- }
|