C 算法精介绍---二叉树的定义和介绍

   前面对二叉树有了简单的认识,下面就先介绍下二叉树的定义和分析(以下是自己对函数分析):值得一说的就是在bitree_ins_left()函数中定义的二级指针position的使用。如何不是在图纸上画了下,我可能还没有理解用法。这个可能需要修改下,更容易理解。

 

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


 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值