tree.h
#ifndef TREE_H
#define TREE_H
/*
*二叉搜索树程序接口
*/
#define TREE_TYPE int /* define the value type of the tree*/
/*
*insert
*add value to tree ,the value must not exist in the tree
*/
void insert(TREE_TYPE value);
/*
*find
*find the value from tree ,return the value as the first parameter
*/
TREE_TYPE *find(TREE_TYPE value);
/*
*pre_order_traverse
*执行树的前序遍历,它的参数是一个回调函数指针,
*它所指向的函数将在树中处理每个节点被调用,节点的值作为参数传递给这个函数
*/
void pre_order_traverse(void(*callback)(TREE_TYPE value));
#endif /*TREE_H*/
tree.c
/*
*使用静态数组实现二叉搜索树
*规则1: 节点N的双亲节点为N/2
* 节点N的左孩子为2N
* 节点N的右孩子为2N+1
*该规则,根节点必须从1开始,所以单个元素所占空间较大时,造成了空间浪费,
*但实现最为简单
*
*规则2: 节点N的双亲节点为(N+1)/2-1
* 节点N的左孩子为2N+1
* 节点N的右孩子为2N+2
*该规则,根节点从0开始
*总:所有树的位置都已经在数组中固定,
* 若树的只有左孩子或者只有右孩子的情况较多,则数组中的空值较多
*本方法使用规则1
*/
#include "tree.h"
#include
#include
#define TREE_SIZE 100 /* 满二叉树最大个数*/
#define ARRAY_SIZE (TREE_SIZE+1) /*使用规则1增加树的容量*/
/*
*define the tree
*/
static TREE_TYPE tree[ARRAY_SIZE];
/*
*left_child postion
*
*/
static int left_child(int current)
{
return current*2;
}
/*
*right_child postion
*
*/
static int right_child(int current)
{
return current*2+1;
}
/*
*insert
*add value to tree ,the value must not exist in the treed
*/
void insert(TREE_TYPE value)
{
/*确保插入的元素值非零,因为数组初始化都为0,
0用于判断该位置是否已经被占有*/
assert(value != 0);
//从下标为1的位置开始查找适合自己的位置下标
int current=1;
/*
*从根节点开始查找适合自己的位置
*如果为叶子节点:
*将新值插入
*否则:
*如果新值小于当前节点的值
*从左子树中搜索合适的位置
*否则:
*判断该值是否已经存在
*从右子树中搜索合适的位置
*/
while(tree[current] != 0)
{
if(value
current=left_child(current);
else
{
assert(value != tree[current]);
current=right_child(current);
}
assert(current
}
tree[current]=value;
printf("tree[%d] is %d\n",current,tree[current]);
}
/*
*find
*find the value from tree ,return the value as the first parameter
*/
TREE_TYPE *find(TREE_TYPE value)
{
int current=1;
while(current
{
if(value < tree[current])
current=left_child(current);
else
current=right_child(current);
}
if(current < ARRAY_SIZE)
return tree+current;//若存在,返回该元素位置的地址
else
return 0;//若不存在,则指针赋值为0,返回NULL指针
}
/*
*do_pre_order_traverse
*执行一层前序遍历,保存当期正在处理的节点的信息
*接口不对用户显示
*/
static void do_pre_order_traverse(int current,void(*callback)(TREE_TYPE value))
{
if(current
{
callback(tree[current]);
printf("%d\t",tree[current]);
do_pre_order_traverse(left_child(current),callback);
do_pre_order_traverse(right_child(current),callback);
}
}
/*
*pre_order_traverse
*执行树的前序遍历,它的参数是一个回调函数指针,
*它所指向的函数将在树中处理每个节点被调用,节点的值作为参数传递给这个函数
*/
void pre_order_traverse(void(*callback)(TREE_TYPE value))
{
do_pre_order_traverse(1,callback);
}
treetest.c
#include
#include "tree.h"
void main()
{
int i=0;
int tre[10]={20,12,25,5,16,28,9,17,26,29};
for(i=0;i<10;i++)
{
insert(tre[i]);
}
printf("find 12 memory address int the tree is %d ( 0:means not in the tree!)\n",find(12));
int *head=tre;
//pre_order_traverse(20);
}