#include "mavl.h" void mavlnode_destroy(struct mavl *t, struct mavlnode *n) { if (t->del) { t->del(mavlnode_dataptr(n)); } free(n); t->count--; } static void rot_rl(struct mavlnode *n, struct mavlnode **parent) { struct mavlnode *tmp; *parent = n->right->left; n->right->left = (*parent)->right; (*parent)->right = n->right; tmp = (*parent)->left; (*parent)->left = n; n->right = tmp; } static void rot_lr(struct mavlnode *n, struct mavlnode **parent) { struct mavlnode *tmp; *parent = n->left->right; n->left->right = (*parent)->left; (*parent)->left = n->left; tmp = (*parent)->right; (*parent)->right = n; n->left = tmp; } static void rot_l(struct mavlnode *n, struct mavlnode **parent) { struct mavlnode *tmp; *parent = n->right; tmp = n->right->left; n->right->left = n; n->right = tmp; } static void rot_r(struct mavlnode *n, struct mavlnode **parent) { struct mavlnode *tmp; *parent = n->left; tmp = n->left->right; n->left->right = n; n->left = tmp; } static int adj_bal_l(struct mavlnode *n, struct mavlnode **parent) { if (n->right->bal == 1) { n->bal = 0; n->right->bal = 0; rot_l(n, parent); return 1; } else if (n->right->bal == 0) { n->bal = 1; n->right->bal = -1; rot_l(n, parent); return 0; } else if (n->right->bal == -1) { n->bal = 0; n->right->bal = 0; n->right->left->bal = 0; rot_rl(n, parent); return 1; } return -11; /* that should never happen */ } static int adj_bal_r(struct mavlnode *n, struct mavlnode **parent) { if (n->left->bal == -1) { n->bal = 0; n->left->bal = 0; rot_r(n, parent); return 1; } else if (n->left->bal == 0) { n->bal = -1; n->left->bal = 1; rot_r(n, parent); return 0; } else if (n->left->bal == 1) { n->bal = 0; n->left->bal = 0; n->left->right->bal = 0; rot_lr(n, parent); return 1; } return -11; /* that should never happen */ } static int mavl_del_lo(mavl_t t, struct mavlnode **parent, void *data) { struct mavlnode *n = *parent; if (n->left != 0) { int bal = mavl_del_lo(t, &n->left, data); n->bal += bal; if (n->bal == 1) { return 0; } if (n->bal != 2) return bal; adj_bal_l(n, parent); return 0; } /* found the lowest element */ *parent = n->right; /* *data = n->data;*/ memcpy(data,mavlnode_dataptr(n),t->data_size); free(n); return 1; if (n->right) { free(n); return 1; } free(n); return 1; } int mavl_del0(struct mavl *t, struct mavlnode **parent, void *data) { struct mavlnode *n = *parent; int rc; int bal; rc = t->cmp(data, mavlnode_dataptr(n)); if (rc == 0) { if (n->right == 0 && n->left == 0) { *parent = 0; mavlnode_destroy(t, n); return 1; } if (n->right && n->left == 0) { *parent = n->right; mavlnode_destroy(t, n); return 1; } if (n->left && n->right == 0) { mavlnode_destroy(t, n); *parent = n->left; return 1; } /* node has two childs */ if (t->del) { t->del(mavlnode_dataptr(n)); } t->count--; bal = mavl_del_lo(t,&n->right, mavlnode_dataptr(n)); n->bal -= bal; if (n->bal == -1) return 0; if (n->bal != -2) return bal; return adj_bal_r(n, parent); } if (rc < 0) { if (n->left) { bal = mavl_del0(t, &n->left, data); if (bal == 2) return 2; n->bal += bal; if (n->bal == 1) return 0; if (n->bal != 2) return bal; return adj_bal_l(n, parent); } return 2; /* not found */ } else { /* rc must be > 0 */ if (n->right) { bal = mavl_del0(t, &n->right, data); if (bal == 2) return 2; n->bal -= bal; if (n->bal == -1) return 0; if (n->bal != -2) return bal; return adj_bal_r(n, parent); } return 2; /* not found */ } } void *mavl_del(struct mavl *t, const void *data) { void *d; int rc; if (!t->root) return NULL; d = (void*)data; rc = mavl_del0(t, &t->root, d); if (rc == 2) return NULL; return (void*)data; }