BTree C 语言实例
生活随笔
收集整理的這篇文章主要介紹了
BTree C 语言实例
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
該代碼摘自《算法精解: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; elseposition = &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; elseposition = &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;}
運行效果;
?
總結
以上是生活随笔為你收集整理的BTree C 语言实例的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 创建和准备Oracle样例数据库
- 下一篇: vs新特性学习总结