算法精解(七):C语言描述(二叉搜索树)

二叉树搜索树概念

  二叉搜索树是由二叉树组成的专用于查找和搜索的一种数据结构。需要在二叉树中查询一个节点,从根节点开始一层层往下查找,直到找到目标节点为止。当遇到一个比目标节点值大的节点时,顺着该节点的左子树继续查找。如果遇到的节点值小于目标节点,则顺着该节点的右子树继续查找。(左分支的数,一定小于右分支的数,个人觉得类似二分查找)

   二叉搜索树是一种用于查找操作的高效数据结构,最坏情况只需查找一个分支 的数据即可,而不用检索所有数据,所以操作的复杂度为O(lg n).

代码实现

#include"bitree.h"
typedef BiTree BisTree;
//初始化二叉搜索树,compare用于比较key1>key2?1:-1(= 0)
void bistree_init(BisTree *tree, void(*compare)(const void *key1, const void *key2),
	void(*destroy)(void *data));

//销毁树
void bistree_destroy(BisTree *tree);

//插入节点,成功返回0,要插入的节点已存在返回1,否则-1
int bistree_insert(BisTree *tree, const void *data);   //复杂度lg n

//移除等于data的节点,成功返回0,否则-1
int bistree_remove(BisTree *tree, const void *data);   //复杂度lg n

//查找对应data的节点,成功返回0,否则-1
int bistree_lookup(const BisTree *tree, void **data);  //复杂度lg n

//销毁node节点开始的左分支
static void destroy_right(BisTree *tree, BiTreeNode *node);
static void destroy_left(BisTree *tree, BiTreeNode *node)
{
	BiTreeNode **position;
	if (tree->size == 0) return;   //如果树节点为0 ,直接返回
	if (node == NULL)    //如果node为null,从根节点开始删除
		position = &tree->root;
	else
		position = &node->left;

	if (*position != NULL)
	{
		//递归消除position开始的左右子树
		destroy_left(tree, *position);
		destroy_right(tree, *position);
		if (tree->destroy != NULL)
		{
			//调用析构函数;
		}

		//释放节点空间,size--
		free((*position)->data);
		free(*position);
		*position = NULL;
		tree->size--;
	}
	return;
}

//在树tree的node节点开始插入data数据
static int insert(BisTree *tree, BiTreeNode **node, const void *data)
{
	int cmpval, retval;
	if (bitree_is_eob(*node))   //如果指定节点没有左右节点,从左节点开始插入
	{
		return bitree_ins_left(tree, *node, data);
	}
	else
	{
		cmpval = tree->compare(data, (*node)->data);   //比较node->data和data的值,data大时,右子树插入
		if (cmpval < 0)
		{
			if (bitree_is_eob((*node)->left)) //如果node->left为空
			{
				if (bitree_ins_left(tree, *node, data) != 0)
					return -1;
			}
			else
			{
				if ((retval = insert(tree, &((*node)->left), data)) != 0)
				{
					return retval;
				}
			}
		}
		else if(cmpval > 0)
		{
			if (bitree_is_eob((*node)->right)) //如果node->left为空
			{
				if (bitree_ins_right(tree, *node, data) != 0)
					return -1;
			}
			else
			{
				if ((retval = insert(tree, &((*node)->right), data)) != 0)
				{
					return retval;
				}
			}
		}
		else  //如果node->data == data,则为数据冲突
		{
			if (tree->destroy != NULL)
				tree->destroy((*node)->data);
			(*node)->data = data;   //此处,不能讲const data赋值给*node->data
		}
	}
	return 0;
}

//在树tree的node节点开始查找data数据
static int lookup(BisTree *tree, BiTreeNode *node,const void **data)
{
	int cmpval, retval;
	if (bitree_is_eob(node)) //node的左右节点不为空
	{
		return -1;
	}

	//比较插入节点和要插入数据的值
	cmpval = tree->compare(*data, node->data);

	if (cmpval < 0)   //如果插入数据小于node->data,在node的左子树寻找位置继续比较
		retval = lookup(tree, node->left, data);
	else if (cmpval > 0)  //如果插入数据大于node->data,在node的右子树寻找位置继续比较
		retval = lookup(tree, node->right, data);
	else   //等于时,取出数据
	{ 
		*data = node->data;
	}

	return retval;
}

void bistree_init(BisTree *tree, int(*compare)(const void *key1, const void *key2), void(*destroy)(void *data))
{
	bitree_init(tree, destroy);
	tree->compare = compare;
	return;
}

void bistree_destroy(BisTree *tree)
{
	destroy_left(tree, NULL);
	memset(tree, 0, sizeof(BisTree));
	return;
}

int bistree_insert(BisTree *tree, const void *data)
{
	return insert(tree, &(tree->root), data);
}

int bistree_remove(BisTree *tree, const void *data)
{
	return lookup(tree, tree->root, &data);
}

int bistree_lookup(BisTree *tree, void **data)
{
	return lookup(tree, tree->root, data);
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章