如果单向线性链式物理结构中每个结点
可以找到多个其他结点就成为了树
树里的所有结点可以分成几层,不同层
之间符合线性规律(任意两层之间
有前后顺序)
树的最上面一层应该只有一个结点,这个
结点叫做树的根结点
根结点可以用来代表整棵树
如果树里两个结点之间有直接联系,这种联系
叫做父子关系。其中靠近根结点的叫做
父结点,另外一个结点叫子结点。
任何结点最多有一个父结点(根结点没有父
结点)
如果任何一个结点最多只有两个子结点则
这种树叫做二叉树
二叉树是最简单的树
二叉树中某个结点的两个子结点分别叫做它的
左子结点和右子结点
二叉树里任何结点都可以作为根结点代表
一棵二叉树
一个结点左子结点代表的树叫做这个结点的
左子树,右子结点代表的树叫做它的右
子树

树的操作大多数都是通过遍历实现的
通常采用递归函数实现树的遍历
遍历的时候左子树一定在右子树前面处理
先处理根结点的遍历方式叫前序遍历
在两个子树之间处理根结点的遍历方式叫
中序遍历
在最后处理根结点的遍历方式叫后序遍历

/*
    二叉树演示
*/
#ifndef    __02TREE_H__
#define    __02TREE_H__
struct node;
typedef struct {
    struct node *p_node;
} tree;
typedef struct node {
    int num;
    tree left;
    tree right;
} node;
//初始化函数
void tree_init(tree *);
//清理函数
void tree_deinit(tree *);
//在有序二叉树里查找某个数字所在的位置
tree *tree_search_in_order(const tree *, int );
//在有序二叉树里插入新数字
void tree_insert_in_order(tree *, int );
//中序遍历函数
void tree_miter(tree *, void (*)(int));
//前序遍历函数
void tree_fiter(tree *, void (*)(int));
//后序遍历函数
void tree_liter(tree *, void (*)(int));
//从有序二叉树里删除数字的函数
void tree_remove(tree *, int);
#endif        //__02TREE_H__







/*
    二叉树演示
*/
#include <stdlib.h>
#include "02tree.h"
//初始化函数
void tree_init(tree *p_tree) {
    p_tree->p_node = NULL;
}
//清理函数
void tree_deinit(tree *p_tree) {
    if (!(p_tree->p_node)) {
        return ;
    }
    tree_deinit(&(p_tree->p_node->left));
    tree_deinit(&(p_tree->p_node->right));
    free(p_tree->p_node);
    p_tree->p_node = NULL;
}
//在有序二叉树里查找某个数字所在的位置
tree *tree_search_in_order(const tree *p_tree, int num) {
    if (!(p_tree->p_node)) {
        return (tree *)p_tree;
    }
    if (p_tree->p_node->num == num) {
        return (tree *)p_tree;
    }
    else if (p_tree->p_node->num > num) {
        return tree_search_in_order(&(p_tree->p_node->left), num);
    }
    else {
        return tree_search_in_order(&(p_tree->p_node->right), num);
    }
}
//在有序二叉树里插入新数字
void tree_insert_in_order(tree *p_tree, int num) {
    tree *p_tr = tree_search_in_order(p_tree, num);
    if (p_tr->p_node) {
        return ;
    }
    node *p_tmp = (node *)malloc(sizeof(node));
    if (!p_tmp) {
        return ;
    }
    p_tmp->num = num;
    p_tmp->left.p_node = NULL;
    p_tmp->right.p_node = NULL;
    p_tr->p_node = p_tmp;
}
//中序遍历函数
void tree_miter(tree *p_tree, void (*p_func)(int)) {
    if (!(p_tree->p_node)) {
        return ;
    }
    tree_miter(&(p_tree->p_node->left), p_func);
    p_func(p_tree->p_node->num);
    tree_miter(&(p_tree->p_node->right), p_func);
}
//前序遍历函数
void tree_fiter(tree *p_tree, void (*p_func)(int)) {
    if (!(p_tree->p_node)) {
        return ;
    }
    p_func(p_tree->p_node->num);
    tree_fiter(&(p_tree->p_node->left), p_func);
    tree_fiter(&(p_tree->p_node->right), p_func);
}
//后序遍历函数
void tree_liter(tree *p_tree, void (*p_func)(int)) {
    if (!(p_tree->p_node)) {
        return ;
    }
    tree_liter(&(p_tree->p_node->left), p_func);
    tree_liter(&(p_tree->p_node->right), p_func);
    p_func(p_tree->p_node->num);
}
//从有序二叉树里删除一个数字的函数
void tree_remove(tree *p_tree, int num) {
    node *p_remove = NULL, *p_left = NULL, *p_right = NULL;
    tree *p_tmp = tree_search_in_order(p_tree, num);
    if (!(p_tmp->p_node)) {
        return ;
    }
    p_remove = p_tmp->p_node;
    p_left = p_remove->left.p_node;
    p_right = p_remove->right.p_node;
    if (!p_left) {
        p_tmp->p_node = p_right;
    }
    else if (!p_right) {
        p_tmp->p_node = p_left;
    }
    else {
        tree *p_tmp1 = tree_search_in_order(&(p_remove->left), p_right->num);
        p_tmp1->p_node = p_right;
        p_tmp->p_node = p_left;
    }
    free(p_remove);
    p_remove = NULL;
}







/*
    树测试
*/
#include <stdio.h>
#include "02tree.h"
void print_cb(int num) {
    printf("%d ", num);
}
int main() {
    tree tr = {0};
    tree_init(&tr);
    tree_insert_in_order(&tr, 50);
    tree_insert_in_order(&tr, 25);
    tree_insert_in_order(&tr, 80);
    tree_insert_in_order(&tr, 13);
    tree_insert_in_order(&tr, 37);
    tree_insert_in_order(&tr, 61);
    tree_insert_in_order(&tr, 93);
    tree_insert_in_order(&tr, 7);
    tree_remove(&tr, 25);
    tree_miter(&tr, print_cb);
    printf("
");
    tree_deinit(&tr);
    return 0;
}
原文地址:https://www.cnblogs.com/LuckCoder/p/8674817.html