/** * This creates a new node in the AVL then returns the created node * so that you might populate it with data. If the key already * exists, then the existing node is returned. * * @param avl the AVL to add a property to. * @param key the key to add to the AVL. * * @return the newly created AVL node. */ PropPtr new_prop(PropPtr *avl, char *key) { PropPtr ret; register PropPtr p = *avl; register int cmp; static short balancep; if (p) { cmp = strcasecmp(key, PropName(p)); if (cmp > 0) { ret = new_prop(&(p->right), key); } else if (cmp < 0) { ret = new_prop(&(p->left), key); } else { balancep = 0; return (p); } if (balancep) { *avl = balance_node(p); } return ret; } else { p = *avl = alloc_propnode(key); balancep = 1; return (p); } }
static PropPtr remove_propnode(char *key, PropPtr * root) { PropPtr save; PropPtr tmp; PropPtr avl = *root; int cmpval; save = avl; if (avl) { cmpval = Comparator(key, PropName(avl)); if (cmpval < 0) { save = remove_propnode(key, &AVL_LF(avl)); } else if (cmpval > 0) { save = remove_propnode(key, &AVL_RT(avl)); } else if (!(AVL_LF(avl))) { avl = AVL_RT(avl); } else if (!(AVL_RT(avl))) { avl = AVL_LF(avl); } else { tmp = remove_propnode(PropName(getmax(AVL_LF(avl))), &AVL_LF(avl)); if (!tmp) abort(); /* this shouldn't be possible. */ AVL_LF(tmp) = AVL_LF(avl); AVL_RT(tmp) = AVL_RT(avl); avl = tmp; } if (save) { AVL_LF(save) = NULL; AVL_RT(save) = NULL; } *root = balance_node(avl); } return save; }
static PropPtr insert(char *key, PropPtr * avl) { PropPtr ret; register PropPtr p = *avl; register int cmp; static short balancep; if (p) { cmp = Comparator(key, PropName(p)); if (cmp > 0) { ret = insert(key, &(AVL_RT(p))); } else if (cmp < 0) { ret = insert(key, &(AVL_LF(p))); } else { balancep = 0; return (p); } if (balancep) { *avl = balance_node(p); } return ret; } else { p = *avl = alloc_propnode(key); balancep = 1; return (p); } }
/** * Remove a propnode named 'key' from the AVL root 'root'. This function * is recursive. * * The node (removed from the AVL structure) is returned, or NULL if it * was not found. * * @private * @param key the prop name to remove * @param root the root node to start the removal process from * * @return the removed node - you should probably free it with free_propnode */ static PropPtr remove_propnode(char *key, PropPtr * root) { PropPtr save; PropPtr tmp; PropPtr avl = *root; int cmpval; save = avl; if (avl) { cmpval = strcasecmp(key, PropName(avl)); if (cmpval < 0) { save = remove_propnode(key, &(avl->left)); } else if (cmpval > 0) { save = remove_propnode(key, &(avl->right)); } else if (!(avl->left)) { avl = avl->right; } else if (!(avl->right)) { avl = avl->left; } else { tmp = remove_propnode(PropName(getmax(avl->left)), &(avl->left)); if (!tmp) { /* this shouldn't be possible. */ panic("remove_propnode() returned NULL !"); } tmp->left = avl->left; tmp->right = avl->right; avl = tmp; } if (save) { save->left = NULL; save->right = NULL; } *root = balance_node(avl); } return save; }