https://github.com/liutianshx2012/Algorithms-Data_structures/tree/master/Data_structures/src2
//
// BiTree.h
// Algorithms&Data_structures
//
// Created by TTc on 15-2-3.
// Copyright (c) 2015年 TTc. All rights reserved.
//
#ifndef __Algorithms_Data_structures__BiTree__
#define __Algorithms_Data_structures__BiTree__
#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)
/*判断分支是否结束*/
#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 /* defined(__Algorithms_Data_structures__BiTree__) */
//
// BiTree.c
// Algorithms&Data_structures
//
// Created by TTc on 15-2-3.
// Copyright (c) 2015年 TTc. All rights reserved.
//
#include "BiTree.h"
#include <stdlib.h>
#include <string.h>
/*二叉树初始化 * O(1) */
void bitree_init(BiTree *tree, void (*destroy)(void *data)) {
tree->size = 0;
tree->destroy = destroy;
tree->root = NULL;
}
/*二叉树销毁 * O(n) */
void bitree_destroy(BiTree *tree) {
/*从二叉树中移除所有的节点*/
bitree_rem_left(tree, NULL);
memset(tree, 0, sizeof(BiTree));
}
/* 将节点插入到二叉树中,插入到由参数tree指定节点node的左子树 * 如果节点为空,且树为空树,就是讲此节点设为root * return 成功返回0,失败-1 * O(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;
/*position指向新节点*/
*position = new_node;
tree->size++;
return 0;
}
/*将节点插入到二叉树中,插入到有参数指定节点的右子树 *如果节点为空,且树为空树,就是讲此节点设为root * return 成功返回0,失败-1 *O(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节点作right孩子是否为空
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指向新节点*/
*position = new_node;
tree->size++;
return 0;
}
/* 按照后序遍历从参数node的左子节点开始一次移除;若node == *NULL,则从根节点root开始依次移除 *无返回值 *O(n) */
void bitree_rem_left(BiTree *tree, BiTreeNode *node) {
BiTreeNode **postion;
/*当为空树时返回*/
if (bitree_size(tree) == 0) {
return;
}
/* 决定删除哪一个节点*/
if (node == NULL)
postion = &tree->root;
else
postion = &node->left;
//删除操作,删除该节点
if (*postion != NULL) {
bitree_rem_left(tree, *postion);
bitree_rem_right(tree, *postion);
if (tree->destroy != NULL) {
tree->destroy((*postion)->data);
}
free(*postion);
*postion = NULL;
tree->size--;
}
}
/*移除node节点的右孩子如果node=NULL 则移除所有节点 *无返回值 *O(n) */
void bitree_rem_right(BiTree *tree, BiTreeNode *node) {
BiTreeNode **postion;
/*当为空树时返回*/
if (bitree_size(tree) == 0) {
return;
}
/* 决定删除哪一个节点*/
if (node == NULL)
postion = &tree->root;
else
postion = &node->right;
//删除操作,删除该节点
if (*postion != NULL) {
bitree_rem_left(tree, *postion);
bitree_rem_right(tree, *postion);
if (tree->destroy != NULL) {
tree->destroy((*postion)->data);
}
free(*postion);
*postion = 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;
}
/* 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 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;
}
//
// test_bitree_main.c
//
//
// Created by TTc on 16/5/25.
//
//
#include <stdio.h>
#include "bitree.h"
#include "list.h"
#include "traverse.h"
/* destroy */
void
destroy(void *data) {
free(data);
return;
}
/* create_tree */
int
create_tree(BiTree *tree, BiTreeNode *node) {
int ret;
int *int_ptr = NULL;
char ch;
scanf("%c", &ch);
if( ch == '#' )
{
return 0;
}
int_ptr = (int *)malloc(sizeof(int));
if( int_ptr == NULL )
return -1;
*int_ptr = ch-48;
if( node == NULL )
{
bitree_init(tree, destroy);
ret = bitree_ins_left(tree, NULL, (void *)int_ptr);
if( ret != 0 )
{
free(int_ptr);
return -1;
}
printf("root is %d\n", *(int *)bitree_data(tree->root));
create_tree(tree, tree->root);
}
else
{
//insert the data into left tree
ret = bitree_ins_left(tree, node, (void *)int_ptr);
if( ret != 0 )
{
free(int_ptr);
return -1;
}
printf("node: %d 's left node is :%d\n", *(int *)bitree_data(node), *(int *)bitree_data(node->left));
ret = create_tree(tree, node->left);
scanf("%c", &ch);
if( ch == '#')
return 0;
int_ptr = (int *)malloc(sizeof(int));
if( int_ptr == NULL )
return -1;
*int_ptr = ch-48;
// insert the data into right tree.
ret = bitree_ins_right(tree, node, (void *)int_ptr);
if( ret != 0 )
{
free(int_ptr);
return -1;
}
printf("node: %d 's right node is :%d\n", *(int *)bitree_data(node), *(int *)bitree_data(node->right));
ret = create_tree(tree, node->right);
}
return 0;
}
/* main */
int
main(int argc, char **argv) {
int ret;
int *int_ptr;
BiTree tree1, tree2, tree_merge;
List list;
ListElmt *member;
BiTreeNode *nd;
/* tree1 as follows : 1 / \ 2 5 / \ / \ 3 4 6 7 */
create_tree(&tree1, NULL); //input "123#4#56#7#"
printf("\nstep1:tree1 build success\n");
/* tree2 as follows: 0 / \ 8 9 / \ / 6 7 3 */
int_ptr = NULL;
create_tree(&tree2, NULL); //input "086#7#93###"
printf("step2:tree2 build success\n");
int_ptr = (int *)malloc(sizeof(int));
if( int_ptr == NULL )
return -1;
*int_ptr = 11;
/* after merged as follow( by tree1 and tree2 ) : 11 / \ 1 0 / \ / \ 2 5 8 9 / \ / \ / \ / \ 3 4 6 9 6 7 3 NULL */
ret = bitree_merge(&tree_merge, &tree1, &tree2, int_ptr);
printf("step3: after merged: there are %d number nodes in the tree_merge.\n", bitree_size(&tree_merge));
/* after remove the right tree: 11 / \ 1 NULL / \ 2 5 / \ / \ 3 4 6 7 */
printf("\nstep4: remove the right tree in tree_merge.\n");
bitree_rem_right(&tree_merge, bitree_root(&tree_merge) );
printf("after remove the right tree, there are %d number nodes in the tree_merge.\n", bitree_size(&tree_merge));
printf("\nstep5: preorder traverse the tree and insert the nodes into the list\n");
list_init(&list, destroy);
ret = preorder( bitree_root(&tree_merge), &list );
printf("according to the sequence of the preorder traversing the tree:\n");
for(member = list_head(&list); member != NULL; member = list_next(member) )
{
printf("%d ", *(int *)list_data(member));
}
printf("\n");
printf("\nsetp6: inorder traverse the tree and insert the nodes into the list\n");
list_init(&list, destroy);
ret = inorder( bitree_root(&tree_merge), &list );
printf("according to the sequence of the inorder traversing the tree:\n");
for(member = list_head(&list); member != NULL; member = list_next(member) )
{
printf("%d ", *(int *)list_data(member));
}
printf("\n");
printf("\nsetp7: postorder traverse the tree and insert the nodes into the list\n");
list_init(&list, destroy);
ret = postorder( bitree_root(&tree_merge), &list );
printf("according to the sequence of the postorder traversing the tree:\n");
for(member = list_head(&list); member != NULL; member = list_next(member) )
{
printf("%d ", *(int *)list_data(member));
}
printf("\n");
printf("\nstep8: delete all the nodes in the tree.\n");
bitree_rem_left( &tree_merge, NULL );
printf("there are %d number nodes.\n", bitree_size(&tree_merge) );
bitree_destroy(&tree_merge);
return 0;
}