int bitree_merge(BiTree *merge, BiTree *left, BiTree *right, const void *data) { /* initialize the merged tree */ bitree_init(merge, left->destroy); /* insert the data for the root node of the merged tree */ if (bitree_insert_left(merge, NULL, data) != 0) { bitree_destroy(merge); return -1; } /* merge the two binary trees into a single binary tree */ bitree_root(merge)->left = bitree_root(left); bitree_root(merge)->right = bitree_root(right); /* adjust the size of the new binary tree */ merge->size = merge->size + bitree_size(left) + bitree_size(right); /* do not let the original trees access the merged nodes */ left->root = NULL; left->size = 0; right->root = NULL; right->size = 0; return 0; }
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); } }
int avltree_insert(AVLTREE *b, void *data) { struct bitree_node *node; if (bitree_size(b) == 0) { node = bitree_insert_left(b, NULL, data); return (node == NULL) ? -1 : 0; } node = search_insert(b, b->root, data); update_height_balance(b, node); return 0; }
static int insert_left(BITREE *b, struct bitree_node *node, void *data) { if (bitree_insert_left(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; }