int main(){ setup(); puts("Add 0-item as BT1's root, BT1: "); bitree_add_left(bt1, NULL, u[0]); bitree_dump(bt1, print); puts(""); puts("Add 1-item as BT2's root, BT2: "); bitree_add_left(bt2, NULL, u[1]); bitree_dump(bt2, print); puts(""); puts("Add 2-item as BT1's root's left child "); bitree_add_left(bt1, bitree_root(bt1), u[2]); puts("Add 3-item as BT1's root's right child "); bitree_add_right(bt1, bitree_root(bt1), u[3]); puts("BT1: "); bitree_dump(bt1, print); puts(""); puts("Add 4-item as BT2's root's left child "); bitree_add_left(bt2, bitree_root(bt2), u[4]); puts("Add 5-item as BT2's root's right child "); bitree_add_right(bt2, bitree_root(bt2), u[5]); puts("BT2: "); bitree_dump(bt2, print); puts(""); printf("BT1 len: %d\n", bitree_size(bt1)); printf("BT2 len: %d\n", bitree_size(bt2)); printf("BT len: %d\n", bitree_size(bt)); puts("Merge BT1 and BT2 to BT: "); bitree_merge(bt, bt1, bt2, u[6]); bitree_dump(bt, print); puts(""); printf("BT len: %d\n", bitree_size(bt)); puts("BT remove left child, BT: "); bitree_remove_left(bt, bitree_root(bt)); bitree_dump(bt, print); puts(""); enddown(); 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; }