BTree C 语言实例

来源:互联网 发布:mysql my.ini在哪里 编辑:程序博客网 时间:2024/06/09 23:56

该代码摘自《算法精解:C语言描述》,一共5个文件;

list.h

/******************************************************************************                                                                            **  -------------------------------- list.h --------------------------------  **                                                                            ******************************************************************************/#ifndef LIST_H#define LIST_H#include <stdlib.h>/******************************************************************************                                                                            **  Define a structure for linked list elements.                              **                                                                            ******************************************************************************/typedef struct ListElmt_ {void               *data;struct ListElmt_   *next;} ListElmt;/******************************************************************************                                                                            **  Define a structure for linked lists.                                      **                                                                            ******************************************************************************/typedef struct List_ {int                size;int                (*match)(const void *key1, const void *key2);void               (*destroy)(void *data);ListElmt           *head;ListElmt           *tail;} List;/******************************************************************************                                                                            **  --------------------------- Public Interface ---------------------------  **                                                                            ******************************************************************************/void list_init(List *list, void (*destroy)(void *data));void list_destroy(List *list);int list_ins_next(List *list, ListElmt *element, const void *data);int list_rem_next(List *list, ListElmt *element, void **data);#define list_size(list) ((list)->size)#define list_head(list) ((list)->head)#define list_tail(list) ((list)->tail)#define list_is_head(list, element) ((element) == (list)->head ? 1 : 0)#define list_is_tail(element) ((element)->next == NULL ? 1 : 0)#define list_data(element) ((element)->data)#define list_next(element) ((element)->next)#endif

traverse.h

/******************************************************************************                                                                            **  ------------------------------ traverse.h ------------------------------  **                                                                            ******************************************************************************/#ifndef TRAVERSE_H#define TRAVERSE_H#include "bitree.h"#include "list.h"/******************************************************************************                                                                            **  --------------------------- Public Interface ---------------------------  **                                                                            ******************************************************************************/int preorder(const BiTreeNode *node, List *list);int inorder(const BiTreeNode *node, List *list);int postorder(const BiTreeNode *node, List *list);#endif

bitree.h

/******************************************************************************                                                                            **  ------------------------------- bitree.h -------------------------------  **                                                                            ******************************************************************************/#ifndef BITREE_H#define BITREE_H#include <stdlib.h>/******************************************************************************                                                                            **  Define a structure for binary tree nodes.                                 **                                                                            ******************************************************************************/typedef struct BiTreeNode_ {void               *data;struct BiTreeNode_ *left;struct BiTreeNode_ *right;                   } BiTreeNode;/******************************************************************************                                                                            **  Define a structure for binary trees.                                      **                                                                            ******************************************************************************/typedef struct BiTree_ {int                size;int                (*compare)(const void *key1, const void *key2);void               (*destroy)(void *data);BiTreeNode         *root;} BiTree;/******************************************************************************                                                                            **  --------------------------- Public Interface ---------------------------  **                                                                            ******************************************************************************/void bitree_init(BiTree *tree, void (*destroy)(void *data));void bitree_destroy(BiTree *tree);int bitree_ins_left(BiTree *tree, BiTreeNode *node, const void *data);int bitree_ins_right(BiTree *tree, BiTreeNode *node, const void *data);void bitree_rem_left(BiTree *tree, BiTreeNode *node);void bitree_rem_right(BiTree *tree, BiTreeNode *node);int bitree_merge(BiTree *merge, BiTree *left, BiTree *right, const void *data);#define bitree_size(tree) ((tree)->size)#define bitree_root(tree) ((tree)->root)#define bitree_is_eob(node) ((node) == NULL)#define bitree_is_leaf(node) ((node)->left == NULL && (node)->right == NULL)#define bitree_data(node) ((node)->data)#define bitree_left(node) ((node)->left)#define bitree_right(node) ((node)->right)#endif


bitree.c
/******************************************************************************                                                                            **  ------------------------------- bitree.c -------------------------------  **                                                                            ******************************************************************************/#include <stdlib.h>#include <string.h>#include "bitree.h"/******************************************************************************                                                                            **  ------------------------------ bitree_init -----------------------------  **                                                                            ******************************************************************************/void bitree_init(BiTree *tree, void (*destroy)(void *data)) {/******************************************************************************                                                                            **  Initialize the binary tree.                                               **                                                                            ******************************************************************************/tree->size = 0;tree->destroy = destroy;tree->root = NULL;return;}/******************************************************************************                                                                            **  ---------------------------- bitree_destroy ----------------------------  **                                                                            ******************************************************************************/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;}/******************************************************************************                                                                            **  ---------------------------- bitree_ins_left ---------------------------  **                                                                            ******************************************************************************/int bitree_ins_left(BiTree *tree, BiTreeNode *node, const void *data) {BiTreeNode         *new_node,                   **position;/******************************************************************************                                                                            **  Determine where to insert the node.                                       **                                                                            ******************************************************************************/if (node == NULL) {   /**************************************************************************   *                                                                         *   *  Allow insertion at the root only in an empty tree.                     *   *                                                                         *   **************************************************************************/   if (bitree_size(tree) > 0)      return -1;   position = &tree->root;   }else {   /**************************************************************************   *                                                                         *   *  Normally allow insertion only at the end of a branch.                  *   *                                                                         *   **************************************************************************/   if (bitree_left(node) != NULL)      return -1;   position = &node->left;}/******************************************************************************                                                                            **  Allocate storage for the node.                                            **                                                                            ******************************************************************************/if ((new_node = (BiTreeNode *)malloc(sizeof(BiTreeNode))) == NULL)   return -1;/******************************************************************************                                                                            **  Insert the node into the tree.                                            **                                                                            ******************************************************************************/new_node->data = (void *)data;new_node->left = NULL;new_node->right = NULL;*position = new_node;/******************************************************************************                                                                            **  Adjust the size of the tree to account for the inserted node.             **                                                                            ******************************************************************************/tree->size++;return 0;}/******************************************************************************                                                                            **  --------------------------- bitree_ins_right ---------------------------  **                                                                            ******************************************************************************/int bitree_ins_right(BiTree *tree, BiTreeNode *node, const void *data) {BiTreeNode         *new_node,                   **position;/******************************************************************************                                                                            **  Determine where to insert the node.                                       **                                                                            ******************************************************************************/if (node == NULL) {   /**************************************************************************   *                                                                         *   *  Allow insertion at the root only in an empty tree.                     *   *                                                                         *   **************************************************************************/   if (bitree_size(tree) > 0)      return -1;   position = &tree->root;   }else {   /**************************************************************************   *                                                                         *   *  Normally allow insertion only at the end of a branch.                  *   *                                                                         *   **************************************************************************/   if (bitree_right(node) != NULL)      return -1;   position = &node->right;}/******************************************************************************                                                                            **  Allocate storage for the node.                                            **                                                                            ******************************************************************************/if ((new_node = (BiTreeNode *)malloc(sizeof(BiTreeNode))) == NULL)   return -1;/******************************************************************************                                                                            **  Insert the node into the tree.                                            **                                                                            ******************************************************************************/new_node->data = (void *)data;new_node->left = NULL;new_node->right = NULL;*position = new_node;/******************************************************************************                                                                            **  Adjust the size of the tree to account for the inserted node.             **                                                                            ******************************************************************************/tree->size++;return 0;}/******************************************************************************                                                                            **  ---------------------------- bitree_rem_left ---------------------------  **                                                                            ******************************************************************************/void bitree_rem_left(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->left;/******************************************************************************                                                                            **  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;}/******************************************************************************                                                                            **  --------------------------- bitree_rem_right ---------------------------  **                                                                            ******************************************************************************/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;}/******************************************************************************                                                                            **  ----------------------------- bitree_merge -----------------------------  **                                                                            ******************************************************************************/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;}

main.c

/******************************************************************************                                                                            **  ex-1.c                                                                    **  ======                                                                    **                                                                            **  Description: Illustrates using a binary tree (see Chapter 9).             **                                                                            ******************************************************************************/#include <stdio.h>#include <stdlib.h>#include "bitree.h"#include "traverse.h"/******************************************************************************                                                                            **  ---------------------------- print_preorder ----------------------------  **                                                                            ******************************************************************************/static void print_preorder(const BiTreeNode *node) {/******************************************************************************                                                                            **  Display the binary tree rooted at the specified node in preorder.         **                                                                            ******************************************************************************/if (!bitree_is_eob(node)) {   fprintf(stdout, "Node=%03d\n", *(int *)bitree_data(node));   if (!bitree_is_eob(bitree_left(node)))      print_preorder(bitree_left(node));   if (!bitree_is_eob(bitree_right(node)))      print_preorder(bitree_right(node));}return;}/******************************************************************************                                                                            **  ----------------------------- print_inorder ----------------------------  **                                                                            ******************************************************************************/static void print_inorder(const BiTreeNode *node) {/******************************************************************************                                                                            **  Display the binary tree rooted at the specified node in inorder.          **                                                                            ******************************************************************************/if (!bitree_is_eob(node)) {   if (!bitree_is_eob(bitree_left(node)))      print_inorder(bitree_left(node));   fprintf(stdout, "Node=%03d\n", *(int *)bitree_data(node));   if (!bitree_is_eob(bitree_right(node)))      print_inorder(bitree_right(node));}return;}/******************************************************************************                                                                            **  ---------------------------- print_postorder ---------------------------  **                                                                            ******************************************************************************/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;}/******************************************************************************                                                                            **  ------------------------------ insert_int ------------------------------  **                                                                            ******************************************************************************/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;}/******************************************************************************                                                                            **  ------------------------------ search_int ------------------------------  **                                                                            ******************************************************************************/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;}/******************************************************************************                                                                            **  --------------------------------- main ---------------------------------  **                                                                            ******************************************************************************/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;}

运行效果;



0 0
原创粉丝点击