先明确几个概念:
树:是一种重要的非线性数据结构,它是数据元素(在树中称为结点)按分支关系组织起来的结构。
二叉树:二叉树是每个节点最多有两个子树的有序树。(树和二叉树的2个主要差别:1. 树中结点的最大度数没有限制,而二叉树结点的最大度数为2;2. 树的结点无左、右之分,而二叉树的结点有左、右之分。)
满二叉树:除最后一层无任何子节点外,每一层上的所有结点都有两个子结点。
完全二叉树:若一棵二叉树至多只有最下面的两层上的结点的度数可以小于2,并且最下层上的结点都集中在该层最左边的若干位置上,则此二叉树成为完全二叉树。
二叉搜索树:又称为二叉排序树。Binary Search Tree,Binary Sort Tree,简写为BST。它或者是一棵空树;或者是具有下列性质的二叉树: (1)若左子树不空,则左子树上所有结点的值均小于它的根结点的值; (2)若右子树不空,则右子树上所有结点的值均大于它的根结点的值; (3)左、右子树也分别为二叉排序树。
下面用链式结构来实现二叉搜索树:
《tree.h》
/*二叉搜索树模块接口*/
#define TREE_TYPE int //树的值类型
//向二叉搜索树中添加一个不重复的新值
void insert(TREE_TYPE value);
//查找特定值
TREE_TYPE *find(TREE_TYPE value);
//先根遍历二叉搜索树,传入一个函数指针,当遍历每个节点时调用。
void pre_order_traverse(void (*callback)(TREE_TYPE value));
//销毁二叉搜索树
void destroy_tree(void);
《l_tree.c》
/*********************使用动态内存分配的链式结构实现二叉搜索树***********************/
#include "tree.h"
#include <stdio.h>
#include <assert.h>
#include <malloc.h>
typedef struct TREE_NODE
{
TREE_TYPE value;
struct TREE_NODE *left;
struct TREE_NODE *right;
} TreeNode;
static TreeNode *tree; //声明指向树根节点的指针
/*插入*/
void insert(TREE_TYPE value)
{
TreeNode *current;
TreeNode **link;
link=&tree;
//找到合适的插入位置
while((current=*link)!=NULL)
{
//根据情况,选择进入左子树或又子树。并确认没有重复的值
if(value<current->value)
{
link=¤t->left;
}
else
{
assert(value!=current->value);
link=¤t->right;
}
}
//分配一个新节点,并链入到二叉搜索树中
current=malloc(sizeof(TreeNode));
assert(current!=NULL);
current->value=value;
current->left=NULL;
current->right=NULL;
*link=current;
}
/*查询*/
TREE_TYPE *find(TREE_TYPE value)
{
TreeNode *current;
current=tree;
while(current!=NULL&¤t->value!=value)
{
if(value<current->value)
{
current=current->left;
}
else {
current=current->right;
}
}
if(current!=NULL)
return ¤t->value;
else
return NULL;
}
/*
*此方法对每一个遍历到的节点执行一次由用户自定义的callback回调函数
*注意,这个函数并不是用户接口的一部分,故声明为static,即:只能在本文件内访问
*/
static void do_pre_order_traverse(TreeNode *current,void (*callback)(TREE_TYPE value))
{
if(current!=NULL)
{
callback(current->value);
do_pre_order_traverse(current->left,callback);
do_pre_order_traverse(current->right,callback);
}
}
/*遍历*/
void pre_order_traverse(void (*callback)(TREE_TYPE value))
{
do_pre_order_traverse(tree,callback);
}
static void do_destroy_tree(TreeNode *current)
{
if(current!=NULL)
{
do_destroy_tree(current->left);
do_destroy_tree(current->right);
free(current);
}
}
/*销毁*/
void destroy_tree(void)
{
do_destroy_tree(tree);
}
《test_tree.c》
#include "tree.h"
#include <stdio.h>
#include <stdlib.h>
void callback(TREE_TYPE);
int main(void)
{
printf("test tree.\n");
int i;
int value,*ret;
//插入6个节点
for(i=0;i<6;i++)
{
printf("value:");
scanf("%d",&value);
insert(value);
}
printf("\n");
//遍历输出
pre_order_traverse(callback);
printf("\n");
//查找节点
for(i=0;i<3;i++)
{
printf("find value:");
scanf("%d",&value);
ret=find(value);
if(ret==NULL)
printf("not found\n");
else
printf("ok,value:%d\n",*ret);
}
//销毁二叉树
destroy_tree();
return 0;
}
void callback(TREE_TYPE value)
{
printf("%d,",value);
//You can do something else here.
}
所需编译命令:
gcc -c l_tree.c -o l_tree.o
ar crv libmytree.a l_tree.o
gcc test_tree.c -o test_tree -L. -lmytree
测试结果如下图所示:
![](https://img-my.csdn.net/uploads/201301/22/1358840805_5629.png)