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; }
static void preorder_tree(const BiTreeNode *node) { /***************************************************************************** * * * Display the binary search tree rooted at the specified node. * * * *****************************************************************************/ if (!bitree_is_eob(node)) { fprintf(stdout, "Node=%s, %+2d, hidden=%d\n", (char *)((AvlNode *) bitree_data(node))->data, ((AvlNode *)bitree_data(node))->factor, ((AvlNode *)bitree_data(node))->hidden); if (!bitree_is_eob(bitree_left(node))) preorder_tree(bitree_left(node)); if (!bitree_is_eob(bitree_right(node))) preorder_tree(bitree_right(node)); } return; }
static int hide (BisTree *tree, BiTreeNode *node, const void *data) { int cmpval, retval; if (bitree_is_eob (node)) { /* Return that the data was not found. */ return -1; } cmpval = tree->compare (data, ((AvlNode *) bitree_data (node))->data); if (cmpval < 0) { /* Move to the left. */ retval = hide (tree, bitree_left (node), data); } else if (cmpval > 0) { /* Move to the right. */ retval = hide (tree, bitree_right (node), data); } else { /* Mark the node as hidden. */ ((AvlNode *) bitree_data (node))->hidden = 1; retval = 0; } return retval; }
static void build_table(BiTreeNode *node, unsigned short code, unsigned char size, HuffCode *table) { if (!bitree_is_eob(node)) { if (!bitree_is_eob(bitree_left(node))) { /*********************************************************************** * * * Move to the left and append 0 to the current code. * * * ***********************************************************************/ build_table(bitree_left(node), code << 1, size + 1, table); } if (!bitree_is_eob(bitree_right(node))) { /*********************************************************************** * * * Move to the right and append 1 to the current code. * * * ***********************************************************************/ build_table(bitree_right(node), (code << 1) | 0x0001, size + 1, table); } if (bitree_is_eob(bitree_left(node))&&bitree_is_eob(bitree_right(node))) { /*********************************************************************** * * * Ensure that the current code is in big-endian format. * * * ***********************************************************************/ code = htons(code); /*********************************************************************** * * * Assign the current code to the symbol in the leaf node. * * * ***********************************************************************/ table[((HuffNode *)bitree_data(node))->symbol].used = 1; table[((HuffNode *)bitree_data(node))->symbol].code = code; table[((HuffNode *)bitree_data(node))->symbol].size = size; } } return; }
void report1_format(const BiTreeNode *node) { printf("%s\t\t", (char *)((TNode *)((AvlNode *) bitree_data(node))->data)->vname); print_nodechildren(node); print_lineno((List *)((TNode *)((AvlNode *) bitree_data(node))->data)->appear); return; };
void report2_format(const BiTreeNode *node) { printf("%s %d ", (char *)((TNode *)((AvlNode *) bitree_data(node))->data)->vname, list_size((List *)((TNode *)((AvlNode *) bitree_data(node))->data)->appear) ); print_formatedlist((List *)((TNode *)((AvlNode *) bitree_data(node))->data)->appear); return; };
int preorder (const BiTreeNode *node, List *list) { if (!bitree_is_eob(node)) { // problem with insert data into list if (list_ins_next(list, list_tail(list), bitree_data(node)) != 0) { return -1; } // traverse the non-NULL left node if (!bitree_is_eob(bitree_left(node))) { if (preorder(bitree_left(node), list) != 0) { return -1; } } // traverse the non_NULL right node if (!bitree_is_eob(bitree_right(node))) { if (preorder(bitree_right(node), list) != 0) { return -1; } } } return 0; }
void print_nodechildren(const BiTreeNode *node) { printf("%s\t\t\t%s\t\t\t", ((!bitree_is_eob(bitree_right(node))) ? ((char *)((TNode *)((AvlNode *) bitree_data(bitree_right(node)))->data)->vname) : "NIL"), ((!bitree_is_eob(bitree_left(node))) ? ((char *)((TNode *)((AvlNode *) bitree_data(bitree_left(node)))->data)->vname) : "NIL") ); return; };
int postorder(const BiTreeNode *node, List *list) { /***************************************************************************** * * * Load the list with a postorder listing of the tree. * * * *****************************************************************************/ if (!bitree_is_eob(node)) { if (!bitree_is_eob(bitree_left(node))) if (postorder(bitree_left(node), list) != 0) return -1; if (!bitree_is_eob(bitree_right(node))) if (postorder(bitree_right(node), list) != 0) return -1; if (list_ins_next(list, list_tail(list), bitree_data(node)) != 0) return -1; } return 0; }
/** * 前序遍历二叉树 */ int preorder(const BiTreeNode *node, List *list) { if (!bitree_is_eob(node)) { if (list_ins_next(list, list_tail(list), bitree_data(node)) != 0) { printf("%s\n", "preorder() insert node into list fail."); return -1; } //不是没有下级节点的节点 if (!bitree_is_eob(bitree_left(node))) { if (preorder(bitree_left(node), list) != 0) { //递归调用 printf("%s\n", "preorder() left tree order fail."); return -1; } if(!bitree_is_eob(bitree_right(node))) { if(preorder(bitree_right(node), list) != 0) {//递归调用 printf("%s\n", "preorder() right tree order end."); return -1; } } } } return 0; }
int postorder(const BiTreeNode *node) { if (!bitree_is_eob(node)) { if (!bitree_is_eob(bitree_left(node))) if(postorder(bitree_left(node)) != 0) return(-1); if (!bitree_is_eob(bitree_right(node))) if(postorder(bitree_right(node)) != 0) return(-1); fprintf(stdout, "Node=%s (size: %d), %+2d, hidden=%d\n", (char *)((TNode *)((AvlNode *)bitree_data(node))->data)->vname, list_size((List *)((TNode *)((AvlNode *)bitree_data(node))->data)->appear), ((AvlNode *)bitree_data(node))->factor, ((AvlNode *)bitree_data(node))->hidden); } return(0); }
static int lookup (AvlTree *tree, BiTreeNode *node, void **data) { int cmpval, retval = -1; if (bitree_is_eob(tree)) return retval; cmpval = tree->compare(*data, ((AvlTreeNode *)bitree_data(node))->data); if (cmpval < 0) { retval = lookup(tree, bitree_left(node), data); } else if (cmpval > 0) { retval = lookup(tree, bitree_right(node), data); } else { if (!((AvlTreeNode *)bitree_data(node))->hidden) { *data = ((AvlTreeNode *)bitree_data(node))->data; retval = 0; } else { retval = -1; } } return retval; }
static int compare_freq(const void *tree1, const void *tree2) { HuffNode *root1, *root2; /***************************************************************************** * Compare the frequencies stored in the root nodes of two binary trees. * *****************************************************************************/ root1 = (HuffNode *) bitree_data(bitree_root((const BiTree *)tree1)); root2 = (HuffNode *) bitree_data(bitree_root((const BiTree *)tree2)); if (root1->freq < root2->freq) return 1; else if (root1->freq > root2->freq) return -1; else return 0; }
static int lookup (BisTree *tree, BiTreeNode *node, void **data) { int cmpval, retval; if (bitree_is_eob (node)) { /* Return that the data was not found. */ return -1; } cmpval = tree->compare (*data, ((AvlNode *) bitree_data (node))->data); if (cmpval < 0) { /* Move to the left. */ retval = lookup (tree, bitree_left (node), data); } else if (cmpval > 0) { /* Move to the right. */ retval = lookup (tree, bitree_right (node), data); } else { if (!((AvlNode *) bitree_data (node))->hidden) { /* Pass back the data from the tree. */ *data = ((AvlNode *) bitree_data (node))->data; retval = 0; } else { /* Return that the data was not found. */ return -1; } } return retval; }
static BiTreeNode *search_int(BiTree *tree, int i) { BiTreeNode *node; /***************************************************************************** * * * Look up i assuming a binary tree organized as a binary search tree. * * * *****************************************************************************/ node = bitree_root(tree); while (!bitree_is_eob(node)) { if (i == *(int *)bitree_data(node)) { return node; } else if (i < *(int *)bitree_data(node)) { node = bitree_left(node); } else { node = bitree_right(node); } } return NULL; }
/* 后序遍历 */ int postorder(const BiTreeNode *node, List *list) { if (!bitree_is_eob(node)) { /* 左 */ if (!bitree_is_eob(bitree_left(node))) if (postorder(bitree_left(node), list) != 0) return -1; /* 右 */ if (!bitree_is_eob(bitree_right(node))) if (postorder(bitree_right(node), list) != 0) return -1; /* 根 */ if (list_ins_next(list, list_tail(list), bitree_data(node)) != 0) return -1; } return 0; }
int inorder(const BiTreeNode *node, List *list) { if(!bitree_is_eob(node)) { if(!bitree_is_eob(bitree_left(node))) { if(inorder(bitree_left(node), list) != 0) return -1; } if(list_ins_next(list, list_tail(list), bitree_data(node)) != 0) return -1; if(!bitree_is_eob(bitree_right(node))) { if(inorder(bitree_right(node), list) != 0) return -1; } } return 0; }
static void print_postorder(const BiTreeNode *node) { /***************************************************************************** * * * Display the binary tree rooted at the specified node in postorder. * * * *****************************************************************************/ if (!bitree_is_eob(node)) { if (!bitree_is_eob(bitree_left(node))) print_postorder(bitree_left(node)); if (!bitree_is_eob(bitree_right(node))) print_postorder(bitree_right(node)); fprintf(stdout, "Node=%03d\n", *(int *)bitree_data(node)); } return; }
/** * 后序遍历二叉树 */ int postorder(const BiTreeNode *node, List *list){ if(!bitree_is_eob(node)){ if(!bitree_is_eob(bitree_left(node))){ if(inorder(bitree_left(node), list) != 0){ printf("%s\n","postorder() left tree order end"); return -1; } } if(!bitree_is_eob(bitree_right(node))){ if(inorder(bitree_right(node), list) != 0){ printf("%s\n", "postorder() right tree order end"); return -1; } } if(list_ins_next(list, list_tail(list), bitree_data(node)) != 0){ printf("%s\n", "postorder() add node to list fail."); return -1; } } 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; }
static void rotate_right(BiTreeNode **node) { BiTreeNode *right, *grandchild; right = bitree_right(*node); // RR rotate if (((AvlTreeNode *)bitree_data(right))->factor == AVL_RIGHT_HEAVY) { bitree_right(*node) = bitree_left(right); bitree_left(right) = *node; ((AvlTreeNode *)bitree_data(*node))->factor = AVL_BALANCED; ((AvlTreeNode *)bitree_data(right))->factor = AVL_BALANCED; *node = right; // RL rotate } else { grandchild = bitree_left(right); bitree_left(right) = bitree_right(grandchild); bitree_right(grandchild) = right; bitree_right(*node) = bitree_left(grandchild); bitree_left(grandchild) = *node; switch (((AvlTreeNode *)bitree_data(grandchild))->factor) { case AVL_LEFT_HEAVY: ((AvlTreeNode *)bitree_data(*node))->factor = AVL_BALANCED; ((AvlTreeNode *)bitree_data(right))->factor = AVL_RIGHT_HEAVY; break; case AVL_BALANCED: ((AvlTreeNode *)bitree_data(*node))->factor = AVL_BALANCED; ((AvlTreeNode *)bitree_data(right))->factor = AVL_BALANCED; break; case AVL_RIGHT_HEAVY: ((AvlTreeNode *)bitree_data(*node))->factor = AVL_LEFT_HEAVY; ((AvlTreeNode *)bitree_data(right))->factor = AVL_BALANCED; break; } ((AvlTreeNode *)bitree_data(grandchild))->factor = AVL_BALANCED; *node = grandchild; } return; }
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; }
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; }
int huffman_uncompress(const unsigned char *compressed, unsigned char **original) { BiTree *tree; BiTreeNode *node; int freqs[UCHAR_MAX + 1], hsize, size, ipos, opos, state, c; unsigned char *orig, *temp; /***************************************************************************** * * * Initially there is no buffer of original data. * * * *****************************************************************************/ *original = orig = NULL; /***************************************************************************** * * * Get the header information from the buffer of compressed data. * * * *****************************************************************************/ hsize = sizeof(int) + (UCHAR_MAX + 1); memcpy(&size, compressed, sizeof(int)); for (c = 0; c <= UCHAR_MAX; c++) freqs[c] = compressed[sizeof(int) + c]; /***************************************************************************** * * * Rebuild the Huffman tree used previously to compress the data. * * * *****************************************************************************/ if (build_tree(freqs, &tree) != 0) return -1; /***************************************************************************** * * * Uncompress the data. * * * *****************************************************************************/ ipos = hsize * 8; opos = 0; node = bitree_root(tree); while (opos < size) { /************************************************************************** * * * Get the next bit in the compressed data. * * * **************************************************************************/ state = bit_get(compressed, ipos); ipos++; if (state == 0) { /*********************************************************************** * * * Move to the left. * * * ***********************************************************************/ if (bitree_is_eob(node) || bitree_is_eob(bitree_left(node))) { bitree_destroy(tree); free(tree); return -1; } else node = bitree_left(node); } else { /*********************************************************************** * * * Move to the right. * * * ***********************************************************************/ if (bitree_is_eob(node) || bitree_is_eob(bitree_right(node))) { bitree_destroy(tree); free(tree); return -1; } else node = bitree_right(node); } if (bitree_is_eob(bitree_left(node))&&bitree_is_eob(bitree_right(node))) { /*********************************************************************** * * * Write the symbol in the leaf node to the buffer of original data. * * * ***********************************************************************/ if (opos > 0) { if ((temp = (unsigned char *)realloc(orig, opos + 1)) == NULL) { bitree_destroy(tree); free(tree); free(orig); return -1; } orig = temp; } else { if ((orig = (unsigned char *)malloc(1)) == NULL) { bitree_destroy(tree); free(tree); return -1; } } orig[opos] = ((HuffNode *)bitree_data(node))->symbol; opos++; /*********************************************************************** * * * Move back to the top of the tree. * * * ***********************************************************************/ node = bitree_root(tree); } } bitree_destroy(tree); free(tree); /***************************************************************************** * * * Point to the buffer of original data. * * * *****************************************************************************/ *original = orig; /***************************************************************************** * * * Return the number of bytes in the original data. * * * *****************************************************************************/ return opos; }
static void rotate_left (BiTreeNode **node) { BiTreeNode *left, *grandchild; left = bitree_left (*node); if (((AvlNode *) bitree_data (left))->factor == AVL_LFT_HEAVY) { /* Perform an LL rotation. */ bitree_left (*node) = bitree_right (left); bitree_right (left) = *node; ((AvlNode *) bitree_data (*node))->factor = AVL_BALANCED; ((AvlNode *) bitree_data (left))->factor = AVL_BALANCED; *node = left; } else { /* Perform an LR rotation. */ grandchild = bitree_right (left); bitree_right (left) = bitree_left (grandchild); bitree_left (grandchild) = left; bitree_left (*node) = bitree_right (grandchild); bitree_right (grandchild) = *node; switch (((AvlNode *) bitree_data (grandchild))->factor) { case AVL_LFT_HEAVY: ((AvlNode *) bitree_data (*node))->factor = AVL_RGT_HEAVY; ((AvlNode *) bitree_data (left))->factor = AVL_BALANCED; break; case AVL_BALANCED: ((AvlNode *) bitree_data (*node))->factor = AVL_BALANCED; ((AvlNode *) bitree_data (left))->factor = AVL_BALANCED; break; case AVL_RGT_HEAVY: ((AvlNode *) bitree_data (*node))->factor = AVL_BALANCED; ((AvlNode *) bitree_data (left))->factor = AVL_LFT_HEAVY; break; } ((AvlNode *) bitree_data (grandchild))->factor = AVL_BALANCED; *node = grandchild; } return; }