c语言--静态数组创建树

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 <assert.h>
#include <stdio.h>

#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<tree[current])
		current=left_child(current);
		else
		{
			assert(value != tree[current]);				
			current=right_child(current);
		}
		assert(current<ARRAY_SIZE);
	}
	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<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;//若不存在,则指针赋值为0,返回NULL指针
}
/*
*	do_pre_order_traverse
*	执行一层前序遍历,保存当期正在处理的节点的信息
*	接口不对用户显示
*/
static void do_pre_order_traverse(int current,void(*callback)(TREE_TYPE value))
{
	if(current<ARRAY_SIZE && tree[current] !=0 )
	{
		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 <stdio.h>
#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);
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值