static struct bitree_node * search_insert(AVLTREE *b, struct bitree_node *node, void *data) { if (b->compare(data, node->data) > 0) { if (node->right == NULL) return bitree_insert_right(b, node, data); return search_insert(b, node->right, data); } else { if (node->left == NULL) return bitree_insert_left(b, node, data); return search_insert(b, node->left, data); } }
static int insert_right(BITREE *b, struct bitree_node *node, void *data) { if (bitree_insert_right(b, node, data) == NULL) return -1; return 0; }
static int insert(Bitree *tree, BiTreeNode **node, const void *data, int *balanced) { AvlTreeNode *avlnode; int result, compare; if (bitree_is_eob(*node)) { if ((avlnode = (AvlTreeNode *)malloc(sizeof(AvlTreeNode))) == NULL) return -1; avlnode->factor = 0; avlnode->data = (void *)data; avlnode->hidden = 0; return bitree_insert_left(tree, *node, avlnode); } else { compare = tree->compare(data, ((AvlTreeNode *)bitree_data(*node))->data); if (compare < 0) { if (bitree_is_eob(bitree_left(*node))) { if ((avlnode = (AvlTreeNode *)malloc(sizeof(AvlTreeNode))) == NULL) return -1; avlnode->factor = 0; avlnode->data = (void *)data; avlnode->hidden = 0; if (bitree_insert_left(tree, *node, avlnode) != 0) return -1; *balanced = 0; } else { if ((result = insert(tree, &bitree_left(*node), data, balanced)) != 0) { return result; } } if (!(*balanced)) { switch (((AvlTreeNode *)bitree_data(*node))->factor) { case AVL_LEFT_HEAVY: rotate_left(node); *balanced = 1; break; case AVL_BALANCED: ((AvlTreeNode *)bitree_data(*node))->factor = AVL_LEFT_HEAVY; break; case AVL_RIGHT_HEAVY: ((AvlTreeNode *)bitree_data(*node))->factor = AVL_BALANCED; *balanced = 1; break; } } } else if (compare > 0) { if (bitree_is_eob(bitree_right(*node))) { if ((avlnode = (AvlTreeNode *)malloc(sizeof(AvlTreeNode))) == NULL) return -1; avlnode->factor = 0; avlnode->data = (void *)data; avlnode->hidden = 0; if (bitree_insert_right(tree, *node, avlnode) != 0) return -1; *balanced = 0; } else { if ((result = insert(tree, &bitree_right(*node), data, balanced)) != 0) { return result; } } if (!(*balanced)) { switch (((AvlTreeNode *)bitree_data(*node))->factor) { case AVL_LEFT_HEAVY: ((AvlTreeNode *)bitree_data(*node))->factor = AVL_BALANCED; *balanced = 1; break; case AVL_BALANCED: ((AvlTreeNode *)bitree_data(*node))->factor = AVL_RIGHT_HEAVY; break; case AVL_RIGHT_HEAVY: rotate_right(node); *balanced = 1; break; } } } else { if (!((AvlTreeNode *)bitree_data(*node))->hidden) { return 1; } else { if (tree->destory != NULL) tree->destory(((AvlTreeNode *)bitree_data(*node))->data); ((AvlTreeNode *)bitree_data(*node))->data = (void *)data; ((AvlTreeNode *)bitree_data(*node))->hidden = 0; *balanced = 1; } } } return 0; }