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 mid_order_traverse( void (*callback)(TREE_TYPE value) );
// 执行树的后序遍历,它的参数是一个回调函数指针,它所指向的函数将在
// 树中处理每个结点时被调用,结点的值作为参数传递给这个函数.
void back_order_traverse( void (*callback)(TREE_TYPE value) );
// --------------------------外部接口-------------------------------
// 临时函数
void treeprint();
tree.c:
/*
** 使用静态数组实现二叉搜索树
*/
#include "tree.h"
#include
#include
#define TREE_SIZE 100
#define ARRAY_SIZE (TREE_SIZE + 1)
static TREE_TYPE tree[ARRAY_SIZE];
//计算左孩子的下标
static int left_child(int current)
{
return current * 2;
}
//计算右孩子的下标
static int right_child(int current)
{
return current * 2 + 1;
}
void insert(TREE_TYPE value)
{
int current;
//确保值非0,因为0用于提示一个未使用的节点
assert(value != 0);
//从根节点开始
current = 1;
//从合适的子树开始,直到到达一个叶节点
while(tree[current] != 0)
{
if(value < tree[current])
{
current = left_child(current);
}
else
{
assert(value != tree[current]);
current = right_child(current);
}
assert(current < ARRAY_SIZE);
}
tree[current] = value;
}
TREE_TYPE *find(TREE_TYPE value)
{
int current;
//从根节点开始,直到找到那个值,进入合适的子树
current = 1;
while(current < ARRAY_SIZE && tree[current] != value)
{
//根据情况进入左子树或右子树
if(value < tree[current])
{
current = left_child(current);
}
else
{
current = right_child(current);
}
}
if(current < ARRAY_SIZE)
return tree + current;
else
return 0;
}
//执行一层前序遍历,这个帮助函数用于保存我们当前正在处理的节点的信息
//它并不是用户接口的一部分
static void do_pre_order_traverse(int current, void (*callback)(TREE_TYPE value))
{
if(current < ARRAY_SIZE && tree[current] != 0)
{
callback(tree[current]);
do_pre_order_traverse(left_child(current), callback);
do_pre_order_traverse(right_child(current), callback);
}
}
// 执行一次中序遍历,这个帮助函数用于保存我们当前正在处理的节点的信息
// 它并不是用户接口的一部分
static void do_mid_order_traverse( int current, void (*callback)( TREE_TYPE value) )
{
if( current < ARRAY_SIZE && tree[ current ] != 0)
{
do_mid_order_traverse( left_child(current), callback);
callback( tree[ current ] );
do_mid_order_traverse( right_child(current), callback);
}
}
// 执行一次后序遍历,这个帮助函数用于保存我们当前正在处理的节点的信息
// 它并不是用户接口的一部分
static void do_back_order_traverse( int current, void (*callback)( TREE_TYPE value) )
{
if( current < ARRAY_SIZE && tree[ current ] != 0)
{
do_back_order_traverse( left_child(current), callback);
do_back_order_traverse( right_child(current), callback);
callback( tree[ current ] );
}
}
void pre_order_traverse(void (*callback)(TREE_TYPE value))
{
do_pre_order_traverse(1, callback);
}
void mid_order_traverse( void (*callback)( TREE_TYPE value) )
{
do_mid_order_traverse( 1, callback );
}
void back_order_traverse( void (*callback)( TREE_TYPE value) )
{
do_back_order_traverse( 1, callback );
}
// 临时函数
void treeprint()
{
int i;
printf("打印数组……/n");
for( i = 0; i< ARRAY_SIZE; i++)
{
printf("tree[%d]= %d ", i, tree[ i ]);
if( i % 5 == 0 )
{
printf("/n");
}
}
}
test.c:
#include "tree.h"
#include
void my_callback(TREE_TYPE value)
{
printf("%d ", value);
}
void main()
{
insert(20);
insert(12);
insert(25);
insert(28);
insert(26);
insert(29);
insert(5);
insert(16);
insert(9);
insert(17);
treeprint();
printf("/n先序遍历:");
pre_order_traverse(my_callback);
printf("/n中序遍历:");
mid_order_traverse(my_callback);
printf("/n后序遍历:");
back_order_traverse(my_callback);
printf("/n/n");
}