/* Remove the left tree under the node from the tree */ void bitree_rem_left(BiTree * tree, BiTreeNode * node) { BiTreeNode ** position; // For the situation of tree is empty if (bitree_size(tree) == 0) return; // Determine where to remove nodes if (node == NULL) position = & tree -> root; else position = & node -> left; if (position != NULL) { bitree_rem_left(tree, *position); bitree_rem_right(tree, * position); if (tree -> destroy != NULL) { tree -> destroy ((* position) -> data); } free( *position); *position == NULL; tree -> size--; } return; }
void bitree_rem_right(BiTree * tree, BiTreeNode * node) { BiTreeNode **position; /***************************************************************************** * Do not allow removal from an empty tree. * *****************************************************************************/ if (bitree_size(tree) == 0) return; /***************************************************************************** * Determine where to remove nodes. * *****************************************************************************/ if (node == NULL) position = &tree->root; else position = &node->right; /***************************************************************************** * Remove the nodes. * *****************************************************************************/ if (*position != NULL) { bitree_rem_left(tree, *position); bitree_rem_right(tree, *position); if (tree->destroy != NULL) { /*********************************************************************** * Call a user-defined function to free dynamically allocated data. * ***********************************************************************/ tree->destroy((*position)->data); } free(*position); *position = NULL; /************************************************************************** * Adjust the size of the tree to account for the removed node. * **************************************************************************/ tree->size--; } return; }
void bitree_destroy(BiTree * tree) { /***************************************************************************** * Remove all the nodes from the tree. * *****************************************************************************/ bitree_rem_left(tree, NULL); /***************************************************************************** * No operations are allowed now, but clear the structure as a precaution. * *****************************************************************************/ memset(tree, 0, sizeof(BiTree)); return; }
int main(int argc, char **argv) { BiTree tree; BiTreeNode *node; int i; /***************************************************************************** * * * Initialize the binary tree. * * * *****************************************************************************/ bitree_init(&tree, free); /***************************************************************************** * * * Perform some binary tree operations. * * * *****************************************************************************/ fprintf(stdout, "Inserting some nodes\n"); if (insert_int(&tree, 20) != 0) return 1; if (insert_int(&tree, 10) != 0) return 1; if (insert_int(&tree, 30) != 0) return 1; if (insert_int(&tree, 15) != 0) return 1; if (insert_int(&tree, 25) != 0) return 1; if (insert_int(&tree, 70) != 0) return 1; if (insert_int(&tree, 80) != 0) return 1; if (insert_int(&tree, 23) != 0) return 1; if (insert_int(&tree, 26) != 0) return 1; if (insert_int(&tree, 5) != 0) return 1; fprintf(stdout, "Tree size is %d\n", bitree_size(&tree)); fprintf(stdout, "(Preorder traversal)\n"); print_preorder(bitree_root(&tree)); i = 30; if ((node = search_int(&tree, i)) == NULL) { fprintf(stdout, "Could not find %03d\n", i); } else { fprintf(stdout, "Found %03d...Removing the left tree below it\n", i); bitree_rem_left(&tree, node); fprintf(stdout, "Tree size is %d\n", bitree_size(&tree)); fprintf(stdout, "(Preorder traversal)\n"); print_preorder(bitree_root(&tree)); } i = 99; if ((node = search_int(&tree, i)) == NULL) { fprintf(stdout, "Could not find %03d\n", i); } else { fprintf(stdout, "Found %03d...Removing the right tree below it\n", i); bitree_rem_right(&tree, node); fprintf(stdout, "Tree size is %d\n", bitree_size(&tree)); fprintf(stdout, "(Preorder traversal)\n"); print_preorder(bitree_root(&tree)); } i = 20; if ((node = search_int(&tree, i)) == NULL) { fprintf(stdout, "Could not find %03d\n", i); } else { fprintf(stdout, "Found %03d...Removing the right tree below it\n", i); bitree_rem_right(&tree, node); fprintf(stdout, "Tree size is %d\n", bitree_size(&tree)); fprintf(stdout, "(Preorder traversal)\n"); print_preorder(bitree_root(&tree)); } i = bitree_is_leaf(bitree_root(&tree)); fprintf(stdout, "Testing bitree_is_leaf...Value=%d (0=OK)\n", i); i = bitree_is_leaf(bitree_left((bitree_root(&tree)))); fprintf(stdout, "Testing bitree_is_leaf...Value=%d (0=OK)\n", i); i = bitree_is_leaf(bitree_left(bitree_left((bitree_root(&tree))))); fprintf(stdout, "Testing bitree_is_leaf...Value=%d (1=OK)\n", i); i = bitree_is_leaf(bitree_right(bitree_left((bitree_root(&tree))))); fprintf(stdout, "Testing bitree_is_leaf...Value=%d (1=OK)\n", i); fprintf(stdout, "Inserting some nodes\n"); if (insert_int(&tree, 55) != 0) return 1; if (insert_int(&tree, 44) != 0) return 1; if (insert_int(&tree, 77) != 0) return 1; if (insert_int(&tree, 11) != 0) return 1; fprintf(stdout, "Tree size is %d\n", bitree_size(&tree)); fprintf(stdout, "(Preorder traversal)\n"); print_preorder(bitree_root(&tree)); fprintf(stdout, "(Inorder traversal)\n"); print_inorder(bitree_root(&tree)); fprintf(stdout, "(Postorder traversal)\n"); print_postorder(bitree_root(&tree)); /***************************************************************************** * * * Destroy the binary tree. * * * *****************************************************************************/ fprintf(stdout, "Destroying the tree\n"); bitree_destroy(&tree); return 0; }
/* Destroy a binary tree */ void bitree_destroy (BiTree * tree){ bitree_rem_left(tree, NULL); memset(tree, 0. sizeof(BiTree)); return; }