C 算法精介----二叉树-->分析与实现

//
//  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)
/*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 /* defined(__Algorithms_Data_structures__BiTree__) */
<pre name="code" class="cpp">//
//  BiTree.c
//  Algorithms&Data_structures
//
//  Created by TTc on 15-2-3.
//  Copyright (c) 2015年 TTc. All rights reserved.
//

#include "BiTree.h"
#include <string.h>
#include <stdlib.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(new_node))) == 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(new_node))) == 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;
    }
    
    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;
}













 
 



二叉树的 三种遍历方式

//
//  traverse.h
//  Algorithms&Data_structures
//
//  Created by TTc on 15-2-3.
//  Copyright (c) 2015年 TTc. All rights reserved.
//

#ifndef __Algorithms_Data_structures__traverse__
#define __Algorithms_Data_structures__traverse__

#include <stdio.h>
#include "List.h"
#include "BiTree.h"

/*先序遍历*/
int preOrder(const BiTreeNode *node, List *list);

/*中序遍历*/
int inOrder(const BiTreeNode *node, List *list);

/*后序遍历*/
int postOrder (const BiTreeNode *node, List *list);

#endif /* defined(__Algorithms_Data_structures__traverse__) */

//
//  traverse.c
//  Algorithms&Data_structures
//
//  Created by TTc on 15-2-3.
//  Copyright (c) 2015年 TTc. All rights reserved.
//

#include "traverse.h"
#include <stdlib.h>

/*先序遍历  根->左->右 */
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;
}


你可能感兴趣的:(C 算法精介----二叉树-->分析与实现)