static int insert_int(BiTree *tree, int i) { BiTreeNode *node, *prev; int direction, *data; /***************************************************************************** * * * Insert i assuming a binary tree organized as a binary search tree. * * * *****************************************************************************/ node = tree->root; direction = 0; while (!bitree_is_eob(node)) { prev = node; if (i == *(int *)bitree_data(node)) { return -1; } else if (i < *(int *)bitree_data(node)) { node = bitree_left(node); direction = 1; } else { node = bitree_right(node); direction = 2; } } if ((data = (int *)malloc(sizeof(int))) == NULL) return -1; *data = i; if (direction == 0) return bitree_ins_left(tree, NULL, data); if (direction == 1) return bitree_ins_left(tree, prev, data); if (direction == 2) return bitree_ins_right(tree, prev, data); return -1; }
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_ins_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; }
int main(void) { BiTree * tree; char * a[] = {"kobe", "bryant", "james", "jordan", "johnson"}; List *list; ListNode *node; tree = (BiTree *) malloc(sizeof(BiTree)); if (tree == NULL) return -1; list = (List *) malloc(sizeof(List)); if (list == NULL) return -1; bitree_init(tree, &data_destroy); bitree_ins_left(tree, NULL, a[0]); bitree_ins_left(tree, tree->root, a[1]); bitree_ins_right(tree, tree->root, a[2]); bitree_ins_left(tree, tree->root->left, a[3]); bitree_ins_right(tree, tree->root->left, a[4]); //list init list_init(list, &data_destroy); postorder(tree->root, list); node = list->head; while(node != NULL) { printf("%s\n", (char *) node->data ); node = node->next; } bitree_destroy(tree); list_destroy(list); return 0; }
int main(int argc, char const *argv[]) { //create a unbalanced tree BiTree * unbalanced_tree = (BiTree*)malloc(sizeof(BiTree)); bitree_init(unbalanced_tree, NULL); int tree_node_index[5]; for (int i = 0; i < 5; ++i) { tree_node_index[i] = i; } BiTreeNode * position = NULL; bitree_ins_left(unbalanced_tree, NULL, (void *)&tree_node_index[0]); bitree_ins_left(unbalanced_tree, bitree_root(unbalanced_tree), (void *)&tree_node_index[1]); position = bitree_root(unbalanced_tree)->left; bitree_ins_left(unbalanced_tree, position, (void *)&tree_node_index[2]); position = position->left; bitree_ins_left(unbalanced_tree, position, (void *)&tree_node_index[3]); bitree_ins_right(unbalanced_tree, bitree_root(unbalanced_tree), (void *)&tree_node_index[4]); int balance_check_result = check_balance(bitree_root(unbalanced_tree)); if(balance_check_result < 0) printf("unbalanced tree\n"); else printf("balanced tree\n"); bitree_destroy(unbalanced_tree); free(unbalanced_tree); //create a balanced tree BiTree * balanced_tree = (BiTree *)malloc(sizeof(BiTree)); bitree_init(balanced_tree, NULL); bitree_ins_left(balanced_tree, NULL, (void *)&tree_node_index[0]); bitree_ins_left(balanced_tree, bitree_root(balanced_tree), (void *)&tree_node_index[1]); position = bitree_root(balanced_tree)->left; bitree_ins_left(balanced_tree, position, (void *)&tree_node_index[2]); bitree_ins_right(balanced_tree, position, (void *)&tree_node_index[3]); bitree_ins_right(balanced_tree, bitree_root(balanced_tree), (void *)&tree_node_index[4]); balance_check_result = check_balance(bitree_root(balanced_tree)); if(balance_check_result < 1) printf("unbalanced!\n"); else printf("balanced\n"); bitree_destroy(balanced_tree); free(balanced_tree); return 0; }
struct bitree *build(int n) { int i, *data; struct bitree *tree = NULL; struct bitree_node *position = NULL; tree = (struct bitree *) malloc(sizeof(struct bitree)); if (!tree) return NULL; bitree_init(tree, NULL); data = (int *) malloc(n * sizeof(int)); if (!data) { goto fail; } for (i = 0; i <= n/2; i++) { data[i] = i + 1; if (bitree_ins_left(tree, position, (const void *) &data[i]) != 0) goto fail; if (!position) { if (bitree_root(tree) == NULL) goto fail; position = bitree_root(tree); } else { position = position->left; } } position = bitree_root(tree); for (i = n/2 + 1; i < n; i++) { data[i] = i + 1; if (bitree_ins_right(tree, position, (const void *) &data[i]) != 0) goto fail; position = position->right; } return tree; fail: free(tree); return NULL; }
static int build_tree(int *freqs, BiTree **tree) { BiTree *init, *merge, *left, *right; PQueue pqueue; HuffNode *data; int size, c; /***************************************************************************** * * * Initialize the priority queue of binary trees. * * * *****************************************************************************/ *tree = NULL; pqueue_init(&pqueue, compare_freq, destroy_tree); for (c = 0; c <= UCHAR_MAX; c++) { if (freqs[c] != 0) { /*********************************************************************** * * * Set up a binary tree for the current symbol and its frequency. * * * ***********************************************************************/ if ((init = (BiTree *)malloc(sizeof(BiTree))) == NULL) { pqueue_destroy(&pqueue); return -1; } bitree_init(init, free); if ((data = (HuffNode *)malloc(sizeof(HuffNode))) == NULL) { pqueue_destroy(&pqueue); return -1; } data->symbol = c; data->freq = freqs[c]; if (bitree_ins_left(init, NULL, data) != 0) { free(data); bitree_destroy(init); free(init); pqueue_destroy(&pqueue); return -1; } /*********************************************************************** * * * Insert the binary tree into the priority queue. * * * ***********************************************************************/ if (pqueue_insert(&pqueue, init) != 0) { bitree_destroy(init); free(init); pqueue_destroy(&pqueue); return -1; } } } /***************************************************************************** * * * Build a Huffman tree by merging trees in the priority queue. * * * *****************************************************************************/ size = pqueue_size(&pqueue); for (c = 1; c <= size - 1; c++) { /************************************************************************** * * * Allocate storage for the next merged tree. * * * **************************************************************************/ if ((merge = (BiTree *)malloc(sizeof(BiTree))) == NULL) { pqueue_destroy(&pqueue); return -1; } /************************************************************************** * * * Extract the two trees whose root nodes have the smallest frequencies. * * * **************************************************************************/ if (pqueue_extract(&pqueue, (void **)&left) != 0) { pqueue_destroy(&pqueue); free(merge); return -1; } if (pqueue_extract(&pqueue, (void **)&right) != 0) { pqueue_destroy(&pqueue); free(merge); return -1; } /************************************************************************** * * * Allocate storage for the data in the root node of the merged tree. * * * **************************************************************************/ if ((data = (HuffNode *)malloc(sizeof(HuffNode))) == NULL) { pqueue_destroy(&pqueue); free(merge); return -1; } memset(data, 0, sizeof(HuffNode)); /************************************************************************** * * * Sum the frequencies in the root nodes of the trees being merged. * * * **************************************************************************/ data->freq = ((HuffNode *)bitree_data(bitree_root(left)))->freq + ((HuffNode *)bitree_data(bitree_root(right)))->freq; /************************************************************************** * * * Merge the two trees. * * * **************************************************************************/ if (bitree_merge(merge, left, right, data) != 0) { pqueue_destroy(&pqueue); free(merge); return -1; } /************************************************************************** * * * Insert the merged tree into the priority queue and free the others. * * * **************************************************************************/ if (pqueue_insert(&pqueue, merge) != 0) { pqueue_destroy(&pqueue); bitree_destroy(merge); free(merge); return -1; } free(left); free(right); } /***************************************************************************** * * * The last tree in the priority queue is the Huffman tree. * * * *****************************************************************************/ if (pqueue_extract(&pqueue, (void **)tree) != 0) { pqueue_destroy(&pqueue); return -1; } else { pqueue_destroy(&pqueue); } return 0; }
static int insert (BisTree *tree, BiTreeNode **node, const void *data, int *balanced) { AvlNode *avl_data; int cmpval, retval; /* Insert the data into the tree. */ if (bitree_is_eob (*node)) { /* Handle insertion into an empty tree. */ if ((avl_data = (AvlNode *) malloc (sizeof(AvlNode))) == NULL) return -1; avl_data->factor = AVL_BALANCED; avl_data->hidden = 0; avl_data->data = (void *) data; return bitree_ins_left (tree, *node, avl_data); } else { /* Handle insertion into a tree that is not empty. */ cmpval = tree->compare (data, ((AvlNode *) bitree_data (*node))->data); if (cmpval < 0) { /* Move to the left. */ if (bitree_is_eob (bitree_left (*node))) { if ((avl_data = (AvlNode *) malloc (sizeof(AvlNode))) == NULL) return -1; avl_data->factor = AVL_BALANCED; avl_data->hidden = 0; avl_data->data = (void *) data; if (bitree_ins_left (tree, *node, avl_data) != 0) return -1; *balanced = 0; } else { if ((retval = insert(tree, &bitree_left(*node), data, balanced)) != 0) { return retval; } } /* Ensure that the tree remains balanced. */ if (!(*balanced)) { switch (((AvlNode *) bitree_data (*node))->factor) { case AVL_LFT_HEAVY: rotate_left (node); *balanced = 1; break; case AVL_BALANCED: ((AvlNode *) bitree_data (*node))->factor = AVL_LFT_HEAVY; break; case AVL_RGT_HEAVY: ((AvlNode *) bitree_data (*node))->factor = AVL_BALANCED; *balanced = 1; } } } /* if (cmpval < 0) */ else if (cmpval > 0) { /* Move to the right. */ if (bitree_is_eob (bitree_right (*node))) { if ((avl_data = (AvlNode *) malloc (sizeof(AvlNode))) == NULL) return -1; avl_data->factor = AVL_BALANCED; avl_data->hidden = 0; avl_data->data = (void *) data; if (bitree_ins_right (tree, *node, avl_data) != 0) return -1; *balanced = 0; } else { if ((retval = insert (tree, &bitree_right (*node), data, balanced)) != 0) { return retval; } } /* Ensure that the tree remains balanced. */ if (!(*balanced)) { switch (((AvlNode *) bitree_data (*node))->factor) { case AVL_LFT_HEAVY: ((AvlNode *) bitree_data (*node))->factor = AVL_BALANCED; *balanced = 1; break; case AVL_BALANCED: ((AvlNode *) bitree_data (*node))->factor = AVL_RGT_HEAVY; break; case AVL_RGT_HEAVY: rotate_right (node); *balanced = 1; } } } /* if (cmpval > 0) */ else { /* Handle finding a copy of the data. */ if (!((AvlNode *) bitree_data (*node))->hidden) { /* Do nothing since the data is in the tree and not hidden. */ return 1; } else { /* Insert the new data and mark it as not hidden. */ if (tree->destroy != NULL) { /* Destroy the hidden data since it is being replaced. */ tree->destroy (((AvlNode *) bitree_data (*node))->data); } ((AvlNode *) bitree_data (*node))->data = (void *) data; ((AvlNode *) bitree_data (*node))->hidden = 0; /* Do not rebalance because the tree structure is unchanged. */ *balanced = 1; } } } return 0; }