/*bitree.h*/ #ifndef BITREE_H #define BITREE_H #include <stdlib.h> /*为节点定义二叉树结构体*/ typedef struct BiTreeNode_ { void *data;/*存放数据*/ struct BiTreeNode_ *left;/*左孩子*/ struct BiTreeNode_ *right;/*右孩子*/ }BiTreeNode; /*定义二叉树结构体*/ typedef struct BiTree_ { int size;/*存放数据个数*/ int (*compare) (const void *key1,const void *key2);/*预留的一个接口*/ void (*destroy)(void *data);/*封装的析构函数,作用是释放data空间*/ BiTreeNode *root;/*指向根节点的一个指针*/ }BiTree; /*函数接口*/ 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) /*node标识是树的分子结束*/ #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*/ #include <stdio.h> #include <stdlib.h> #include <string.h> #include "../include/bitree.h" /*二叉树初始化*/ void bitree_init(BiTree * tree, void(* destroy)(void * data)) { tree ->size = 0; tree ->destroy = destroy; tree ->root = NULL; return ; } /*二叉树销毁*/ void bitree_destroy(BiTree * tree) { /*从二叉树中移除所有的节点*/ bitree_rem_left( tree, NULL); memset(tree,0,sizeof(BiTree); return; } /* 将节点插入到二叉树中,插入到有参数指定节点的左子树 *如果节点为空,且树为空树,就是讲此节点设为root * return 成功返回0,失败-1 */ int bitree_ins_left(BiTree * tree, BiTreeNode * node, const void * data) { BiTreeNode *new_node,**position; /*判断该插入到那个节点*/ if (node == NULL){ /*当node==NULL,说明是根节点,但是如果树不为空,则出错返回-1*/ if (bitree_size(tree) > 0){ return -1; } /*这个意思是position指向根节点*/ position = &tree ->root; } else { /*判断node节点左孩子是否为空*/ if (bitree_left(node) != NULL){ return -1; } position = &node->left; } /*申请node空间保存data*/ if ((new_node = (BiTreeNode *)malloc(sizeof(BiTreeNode))) == NULL) return -1; /*将节点插入到二叉树中*/ new_node ->data = (void *)data; new_node ->left = NULL; new_node ->right = NULL; tree->size ++; return 0; } /*将节点插入到二叉树中,插入到有参数指定节点的右子树 *如果节点为空,且树为空树,就是讲此节点设为root * return 成功返回0,失败-1 */ int bitree_ins_right(BiTree * tree, BiTreeNode * node, const void * data) { BiTreeNode *new_node,**position; /*判断该插入到那个节点*/ if (node == NULL){ /*当node==NULL,说明是根节点,但是如果树不为空,则出错返回-1*/ if (bitree_size(tree) > 0){ return -1; } /*这个意思是position指向根节点*/ position = &tree ->root; } else { /*判断node节点左孩子是否为空*/ if (bitree_right(node) != NULL){ return -1; } position = &node->right; } /*申请node空间保存data*/ if ((new_node = (BiTreeNode *)malloc(sizeof(BiTreeNode))) == NULL) return -1; /*将节点插入到二叉树中*/ new_node ->data = (void *)data; new_node ->left = NULL; new_node ->right = NULL; *position = new_node; tree->size ++; return 0; } /*移除node节点的左孩子如果node=NULL 则移除所有节点 *无返回值 */ void bitree_rem_left(BiTree * tree, BiTreeNode * node) { BiTreeNode **position; /*当为空树时返回*/ if (bitree_size(tree) == 0) return; /* 决定删除那个节点*/ 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 --; } /*移除node节点的右孩子如果node=NULL 则移除所有节点 *无返回值 */ void bitree_rem_right(BiTree * tree, BiTreeNode * node) { BiTreeNode **position; /*当为空树时返回*/ if (bitree_size(tree) == 0) return; /* 决定删除那个节点*/ if (node == NULL) position = &tree ->root; else position = &node->right; /*删除这个节点*/ 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 --; } /*合并二叉树*/ int bitree_merge(BiTree * merge, BiTree * left, BiTree * right, const void * data) { /*初始化merger*/ bitree_init(merge, left->destroy); /*如何插入失败则返回-1*/ if (bitree_ins_left(merge, NULL, data) != 0){ bitree_destroy(merge); return -1; } bitree_root(merge)->left = bitree_root(left); bitree_root(merge)->right = bitree_root(right); merge->size += bitree_size(left) + bitree_size(right); left ->root = NULL; left->size = 0; right->root = NULL; right ->size = 0; 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) return -1; if (!bitree_is_eob(bitree_left(node))){ if (preorder(bitree_left(node), list) != 0) return -1; } if (!bitree_is_eob(bitree_right(node))){ if (preorder(bitree_right(node), list) != 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 (preorder(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 (preorder(bitree_right(node), list) != 0) return -1; } } return 0; } /*后序遍历*/ int postorder (const BiTreeNode *node, List *list) { if (!bitree_is_eob(node)){ if (!bitree_is_eob(bitree_left(node))){ if (preorder(bitree_left(node), list) != 0) return -1; } if (!bitree_is_eob(bitree_right(node))){ if (preorder(bitree_right(node), list) != 0) return -1; } if (list_ins_next(list, list_tail(list), bitree_data(node)) != 0) return -1; } return 0; }