123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785 |
- /* The MIT License
- Copyright (C) 2011, 2012 Zilong Tan ([email protected])
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- "Software"), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
- The above copyright notice and this permission notice shall be
- included in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- SOFTWARE.
- */
- #include "tree.h"
- struct tree_root_np *
- tree_search(struct tree_root_np *entry,
- int (*compare)(const void *, const void *),
- struct tree_root_np *root)
- {
- int sgn;
- while (root) {
- sgn = compare(entry, root);
- if (sgn == 0)
- return root;
- if (sgn < 0)
- root = root->left;
- else
- root = root->right;
- }
- return root;
- }
- struct tree_root_np *
- tree_min(struct tree_root_np *root)
- {
- if (root) {
- while (root->left)
- root = root->left;
- }
- return root;
- }
- struct tree_root_np *
- tree_max(struct tree_root_np *root)
- {
- if (root) {
- while (root->right)
- root = root->right;
- }
- return root;
- }
- struct tree_root *
- tree_successor(struct tree_root *entry)
- {
- struct tree_root *succ = NULL;
- if (entry) {
- if (entry->right)
- return (struct tree_root *)TREE_MIN(entry->right);
- succ = entry->parent;
- while (succ && entry == succ->right) {
- entry = succ;
- succ = succ->parent;
- }
- }
- return succ;
- }
- struct tree_root *
- tree_predecessor(struct tree_root *entry)
- {
- struct tree_root *pred = NULL;
- if (entry) {
- if (entry->left)
- return (struct tree_root *)TREE_MAX(entry->left);
- pred = entry->parent;
- while (pred && entry == pred->left) {
- entry = pred;
- pred = pred->parent;
- }
- }
- return pred;
- }
- static inline void
- __rotate_left(struct tree_root *entry, struct tree_root **root)
- {
- struct tree_root *child;
- child = entry->right;
- entry->right = child->left;
- if (child->left)
- child->left->parent = entry;
- child->parent = entry->parent;
- if (entry->parent == NULL)
- *root = child;
- else if (entry == entry->parent->left)
- entry->parent->left = child;
- else
- entry->parent->right = child;
- child->left = entry;
- entry->parent = child;
- }
- static inline void
- __rotate_right(struct tree_root *entry,
- struct tree_root **root)
- {
- struct tree_root *child;
- child = entry->left;
- entry->left = child->right;
- if (child->right)
- child->right->parent = entry;
- child->parent = entry->parent;
- if (entry->parent == NULL)
- *root = child;
- else if (entry == entry->parent->left)
- entry->parent->left = child;
- else
- entry->parent->right = child;
- child->right = entry;
- entry->parent = child;
- }
- void tree_add(struct tree_root *new,
- int (*compare)(const void *, const void *),
- struct tree_root **root)
- {
- int sgn = 0;
- struct tree_root *next = *root;
- struct tree_root *cur = NULL;
- INIT_TREE_ROOT(new);
- while (next) {
- cur = next;
- sgn = compare(new, next);
- if (sgn < 0)
- next = next->left;
- else
- next = next->right;
- }
- new->parent = cur;
- if (cur == NULL)
- *root = new;
- else if (sgn < 0)
- cur->left = new;
- else
- cur->right = new;
- }
- struct tree_root *
- tree_map(struct tree_root *new,
- int (*compare)(const void *, const void *),
- struct tree_root **root)
- {
- int sgn = 0;
- struct tree_root *next = *root;
- struct tree_root *cur = NULL;
- INIT_TREE_ROOT(new);
- while (next) {
- cur = next;
- sgn = compare(new, next);
- if (sgn == 0)
- return next;
- else if (sgn < 0)
- next = next->left;
- else
- next = next->right;
- }
- new->parent = cur;
- if (cur == NULL)
- *root = new;
- else if (sgn < 0)
- cur->left = new;
- else
- cur->right = new;
- return new;
- }
- void
- tree_del(struct tree_root *entry, struct tree_root **root)
- {
- struct tree_root *child;
- struct tree_root *succ;
- if (entry->left == NULL || entry->right == NULL)
- succ = entry;
- else
- succ = TREE_SUCCESSOR(entry);
- if (succ->left)
- child = succ->left;
- else
- child = succ->right;
- if (child)
- child->parent = succ->parent;
- if (succ->parent == NULL)
- *root = child;
- else if (succ == succ->parent->left)
- succ->parent->left = child;
- else
- succ->parent->right = child;
- if (succ != entry) {
- succ->left = entry->left;
- if (entry->left)
- entry->left->parent = succ;
- succ->right = entry->right;
- if (entry->right)
- entry->right->parent = succ;
- succ->parent = entry->parent;
- if (entry->parent == NULL)
- *root = succ;
- else if (entry == entry->parent->left)
- entry->parent->left = succ;
- else
- entry->parent->right = succ;
- }
- }
- #define SPLAY_ROTATE_RIGHT(entry, tmp) do { \
- (entry)->left = (tmp)->right; \
- if ((tmp)->right) (tmp)->right->parent = (entry); \
- (tmp)->right = (entry); \
- (tmp)->parent = (entry)->parent; \
- (entry)->parent = (tmp); \
- (entry) = (tmp); \
- } while (0)
- #define SPLAY_ROTATE_LEFT(entry, tmp) do { \
- (entry)->right = (tmp)->left; \
- if ((tmp)->left) (tmp)->left->parent = (entry); \
- (tmp)->left = (entry); \
- (tmp)->parent = (entry)->parent; \
- (entry)->parent = (tmp); \
- (entry) = (tmp); \
- } while (0)
- #define SPLAY_LINK_RIGHT(entry, large) do { \
- (large)->left = (entry); \
- (entry)->parent = (large); \
- (large) = (entry); \
- (entry) = (entry)->left; \
- } while (0)
- #define SPLAY_LINK_LEFT(entry, small) do { \
- (small)->right = (entry); \
- (entry)->parent = (small); \
- (small) = (entry); \
- (entry) = (entry)->right; \
- } while (0)
- #define SPLAY_ASSEMBLE(head, node, small, large) do { \
- (small)->right = (head)->left; \
- if ((head)->left) \
- (head)->left->parent = (small); \
- (large)->left = (head)->right; \
- if ((head)->right) \
- (head)->right->parent = (large); \
- (head)->left = (node)->right; \
- if ((node)->right) \
- (node)->right->parent = (head); \
- (head)->right = (node)->left; \
- if ((node)->left) \
- (node)->left->parent = (head); \
- } while (0)
- #define SPLAY_ROTATE_RIGHT_NP(entry, tmp) do { \
- (entry)->left = (tmp)->right; \
- (tmp)->right = (entry); \
- (entry) = (tmp); \
- } while (0)
- #define SPLAY_ROTATE_LEFT_NP(entry, tmp) do { \
- (entry)->right = (tmp)->left; \
- (tmp)->left = (entry); \
- (entry) = (tmp); \
- } while (0)
- #define SPLAY_LINK_RIGHT_NP(entry, large) do { \
- (large)->left = (entry); \
- (large) = (entry); \
- (entry) = (entry)->left; \
- } while (0)
- #define SPLAY_LINK_LEFT_NP(entry, small) do { \
- (small)->right = (entry); \
- (small) = (entry); \
- (entry) = (entry)->right; \
- } while (0)
- #define SPLAY_ASSEMBLE_NP(head, node, small, large) do { \
- (small)->right = (head)->left; \
- (large)->left = (head)->right; \
- (head)->left = (node)->right; \
- (head)->right = (node)->left; \
- } while (0)
- struct tree_root *
- splay_search(struct tree_root *entry,
- int (*compare)(const void *, const void *),
- struct tree_root **root)
- {
- int cmp;
- TREE_ROOT(node); /* node for assembly use */
- struct tree_root *small, *large, *head, *tmp;
- head = *root;
- small = large = &node;
- while ((cmp = compare(entry, head)) != 0) {
- if (cmp < 0) {
- tmp = head->left;
- if (tmp == NULL)
- break;
- if (compare(entry, tmp) < 0) {
- SPLAY_ROTATE_RIGHT(head, tmp);
- if (head->left == NULL)
- break;
- }
- SPLAY_LINK_RIGHT(head, large);
- } else {
- tmp = head->right;
- if (tmp == NULL)
- break;
- if (compare(entry, tmp) > 0) {
- SPLAY_ROTATE_LEFT(head, tmp);
- if (head->right == NULL)
- break;
- }
- SPLAY_LINK_LEFT(head, small);
- }
- }
- head->parent = NULL;
- SPLAY_ASSEMBLE(head, &node, small, large);
- *root = head;
- if (cmp != 0)
- return NULL;
- return head;
- }
- struct tree_root *
- splay_map(struct tree_root *new,
- int (*compare)(const void *, const void *),
- struct tree_root **root)
- {
- int cmp;
- TREE_ROOT(node); /* node for assembly use */
- struct tree_root *small, *large, *head, *tmp;
- INIT_TREE_ROOT(new);
- small = large = &node;
- head = *root;
- while (head && (cmp = compare(new, head)) != 0) {
- if (cmp < 0) {
- tmp = head->left;
- if (tmp == NULL) {
- /* zig */
- SPLAY_LINK_RIGHT(head, large);
- break;
- }
- cmp = compare(new, tmp);
- if (cmp < 0) {
- /* zig-zig */
- SPLAY_ROTATE_RIGHT(head, tmp);
- SPLAY_LINK_RIGHT(head, large);
- } else if (cmp > 0) {
- /* zig-zag */
- SPLAY_LINK_RIGHT(head, large);
- SPLAY_LINK_LEFT(head, small);
- } else {
- /* zig */
- SPLAY_LINK_RIGHT(head, large);
- break;
- }
- } else {
- tmp = head->right;
- if (tmp == NULL) {
- /* zag */
- SPLAY_LINK_LEFT(head, small);
- break;
- }
- cmp = compare(new, tmp);
- if (cmp > 0) {
- /* zag-zag */
- SPLAY_ROTATE_LEFT(head, tmp);
- SPLAY_LINK_LEFT(head, small);
- } else if (cmp < 0) {
- /* zag-zig */
- SPLAY_LINK_LEFT(head, small);
- SPLAY_LINK_RIGHT(head, large);
- } else {
- /* zag */
- SPLAY_LINK_LEFT(head, small);
- break;
- }
- }
- }
- if (head == NULL)
- head = new;
- head->parent = NULL;
- SPLAY_ASSEMBLE(head, &node, small, large);
- *root = head;
- return head;
- }
- struct tree_root_np *
- splay_search_np(struct tree_root_np *entry,
- int (*compare)(const void *, const void *),
- struct tree_root_np **root)
- {
- int cmp;
- TREE_ROOT_NP(node); /* node for assembly use */
- struct tree_root_np *small, *large, *head, *tmp;
- head = *root;
- small = large = &node;
- while ((cmp = compare(entry, head)) != 0) {
- if (cmp < 0) {
- tmp = head->left;
- if (tmp == NULL)
- break;
- if (compare(entry, tmp) < 0) {
- SPLAY_ROTATE_RIGHT_NP(head, tmp);
- if (head->left == NULL)
- break;
- }
- SPLAY_LINK_RIGHT_NP(head, large);
- } else {
- tmp = head->right;
- if (tmp == NULL)
- break;
- if (compare(entry, tmp) > 0) {
- SPLAY_ROTATE_LEFT_NP(head, tmp);
- if (head->right == NULL)
- break;
- }
- SPLAY_LINK_LEFT_NP(head, small);
- }
- }
- SPLAY_ASSEMBLE_NP(head, &node, small, large);
- *root = head;
- if (cmp != 0)
- return NULL;
- return head;
- }
- struct tree_root_np *
- splay_map_np(struct tree_root_np *new,
- int (*compare)(const void *, const void *),
- struct tree_root_np **root)
- {
- int cmp;
- TREE_ROOT_NP(node); /* node for assembly use */
- struct tree_root_np *small, *large, *head, *tmp;
- INIT_TREE_ROOT_NP(new);
- small = large = &node;
- head = *root;
- while (head && (cmp = compare(new, head)) != 0) {
- if (cmp < 0) {
- tmp = head->left;
- if (tmp == NULL) {
- /* zig */
- SPLAY_LINK_RIGHT_NP(head, large);
- break;
- }
- cmp = compare(new, tmp);
- if (cmp < 0) {
- /* zig-zig */
- SPLAY_ROTATE_RIGHT_NP(head, tmp);
- SPLAY_LINK_RIGHT_NP(head, large);
- } else if (cmp > 0) {
- /* zig-zag */
- SPLAY_LINK_RIGHT_NP(head, large);
- SPLAY_LINK_LEFT_NP(head, small);
- } else {
- /* zig */
- SPLAY_LINK_RIGHT_NP(head, large);
- break;
- }
- } else {
- tmp = head->right;
- if (tmp == NULL) {
- /* zag */
- SPLAY_LINK_LEFT_NP(head, small);
- break;
- }
- cmp = compare(new, tmp);
- if (cmp > 0) {
- /* zag-zag */
- SPLAY_ROTATE_LEFT_NP(head, tmp);
- SPLAY_LINK_LEFT_NP(head, small);
- } else if (cmp < 0) {
- /* zag-zig */
- SPLAY_LINK_LEFT_NP(head, small);
- SPLAY_LINK_RIGHT_NP(head, large);
- } else {
- /* zag */
- SPLAY_LINK_LEFT_NP(head, small);
- break;
- }
- }
- }
- if (head == NULL)
- head = new;
- SPLAY_ASSEMBLE_NP(head, &node, small, large);
- *root = head;
- return head;
- }
- static inline void
- __avl_balance(struct avl_root *new, struct avl_root **root)
- {
- int balance = 0;
- struct avl_root *child, *grandson;
- while (new->parent && balance == 0) {
- balance = new->parent->balance;
- if (new == new->parent->left)
- new->parent->balance--;
- else
- new->parent->balance++;
- new = new->parent;
- }
- if (new->balance == -2) {
- child = new->left;
- if (child->balance == -1) {
- __rotate_right((struct tree_root *)new,
- (struct tree_root **)root);
- child->balance = 0;
- new->balance = 0;
- } else {
- grandson = child->right;
- __rotate_left((struct tree_root *)child,
- (struct tree_root **)root);
- __rotate_right((struct tree_root *)new,
- (struct tree_root **)root);
- if (grandson->balance == -1) {
- child->balance = 0;
- new->balance = 1;
- } else if (grandson->balance == 0) {
- child->balance = 0;
- new->balance = 0;
- } else {
- child->balance = -1;
- new->balance = 0;
- }
- grandson->balance = 0;
- }
- } else if (new->balance == 2) {
- child = new->right;
- if (child->balance == 1) {
- __rotate_left((struct tree_root *)new,
- (struct tree_root **)root);
- child->balance = 0;
- new->balance = 0;
- } else {
- grandson = child->left;
- __rotate_right((struct tree_root *)child,
- (struct tree_root **)root);
- __rotate_left((struct tree_root *)new,
- (struct tree_root **)root);
- if (grandson->balance == -1) {
- child->balance = 1;
- new->balance = 0;
- } else if (grandson->balance == 0) {
- child->balance = 0;
- new->balance = 0;
- } else {
- child->balance = 0;
- new->balance = -1;
- }
- grandson->balance = 0;
- }
- }
- }
- void avl_add(struct avl_root *new,
- int (*compare)(const void *, const void *),
- struct avl_root **root)
- {
- new->balance = 0;
- TREE_ADD(new, compare, root);
- __avl_balance(new, root);
- }
- struct avl_root *
- avl_map(struct avl_root *new,
- int (*compare)(const void *, const void *),
- struct avl_root **root)
- {
- struct avl_root *node;
- new->balance = 0;
- node = (struct avl_root *)TREE_MAP(new, compare, root);
- if (node != new)
- return node;
- __avl_balance(new, root);
- return new;
- }
- void avl_del(struct avl_root *entry, struct avl_root **root)
- {
- int dir = 0;
- int dir_next = 0;
- struct avl_root *unbalanced, *child, *succ, *parent;
- if (entry->right == NULL) {
- /* Case 1: entry has no right child */
- if (entry->left)
- entry->left->parent = entry->parent;
- if (entry->parent == NULL) {
- *root = entry->left;
- return;
- } else if (entry == entry->parent->left) {
- entry->parent->left = entry->left;
- dir = 0;
- } else {
- entry->parent->right = entry->left;
- dir = 1;
- }
- unbalanced = entry->parent;
- } else if (entry->right->left == NULL) {
- /* Case 2: entry's right child has no left child */
- entry->right->left = entry->left;
- if (entry->left)
- entry->left->parent = entry->right;
- entry->right->parent = entry->parent;
- if (entry->parent == NULL)
- *root = entry->right;
- else if (entry == entry->parent->left)
- entry->parent->left = entry->right;
- else
- entry->parent->right = entry->right;
- entry->right->balance = entry->balance;
- unbalanced = entry->right;
- dir = 1;
- } else {
- /* Case 3: entry's right child has a left child */
- succ = (struct avl_root *)TREE_SUCCESSOR(entry);
- if (succ->right)
- succ->right->parent = succ->parent;
- succ->parent->left = succ->right;
- unbalanced = succ->parent;
- succ->left = entry->left;
- entry->left->parent = succ;
- succ->right = entry->right;
- entry->right->parent = succ;
- succ->parent = entry->parent;
- if (entry->parent == NULL)
- *root = succ;
- else if (entry == entry->parent->left)
- entry->parent->left = succ;
- else
- entry->parent->right = succ;
- succ->balance = entry->balance;
- dir = 0;
- }
- for (;;) {
- parent = unbalanced->parent;
- if (parent)
- dir_next = (unbalanced == parent->right);
- if (dir == 0) {
- ++unbalanced->balance;
- if (unbalanced->balance == 1)
- break;
- if (unbalanced->balance == 2) {
- child = unbalanced->right;
- if (child->balance == -1) {
- succ = child->left;
- __rotate_right((struct tree_root *)child,
- (struct tree_root **)root);
- __rotate_left((struct tree_root *)unbalanced,
- (struct tree_root **)root);
- if (succ->balance == -1) {
- child->balance = 1;
- unbalanced->balance = 0;
- } else if (succ->balance == 0) {
- child->balance = 0;
- unbalanced->balance = 0;
- } else {
- child->balance = 0;
- unbalanced->balance = -1;
- }
- succ->balance = 0;
- } else {
- __rotate_left((struct tree_root *)unbalanced,
- (struct tree_root **)root);
- if (child->balance == 0) {
- child->balance = -1;
- unbalanced->balance = 1;
- break;
- } else {
- child->balance = 0;
- unbalanced->balance = 0;
- }
- }
- }
- } else {
- --unbalanced->balance;
- if (unbalanced->balance == -1)
- break;
- if (unbalanced->balance == -2) {
- child = unbalanced->left;
- if (child->balance == 1) {
- succ = child->right;
- __rotate_left((struct tree_root *)child,
- (struct tree_root **)root);
- __rotate_right((struct tree_root *)unbalanced,
- (struct tree_root **)root);
- if (succ->balance == -1) {
- child->balance = 0;
- unbalanced->balance = 1;
- } else if (succ->balance == 0) {
- child->balance = 0;
- unbalanced->balance = 0;
- } else {
- child->balance = -1;
- unbalanced->balance = 0;
- }
- succ->balance = 0;
- } else {
- __rotate_right((struct tree_root *)unbalanced,
- (struct tree_root **)root);
- if (child->balance == 0) {
- child->balance = 1;
- unbalanced->balance = -1;
- break;
- } else {
- child->balance = 0;
- unbalanced->balance = 0;
- }
- }
- }
- }
- if (parent == NULL)
- break;
- dir = dir_next;
- unbalanced = parent;
- }
- }
|