二叉树的链式存储实现

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;
}

你可能感兴趣的:(二叉树的链式存储实现)