找工作之“二叉搜索树”

今年10月份就要找工作了,数据结构要看起来了。今天终于搞定“二叉搜索树”了,记录在此,日后也好拿来用。

二叉搜索树,就是那么几种操作:1.插入;2.寻找;3.遍历(前、中、后序遍历);4.释放;5.删除。还是比较简单的,直接上代码了。

#define  TREE_TYPE int

typedef struct _Node{
	struct _Node * left;
	struct _Node * right;
	TREE_TYPE value;
} Node;


Node * root = NULL;


//插入
void insert(TREE_TYPE value)
{
	Node * current;
	Node ** nodep;

	nodep = &root;

	while((current = *nodep) != NULL)
	{
		if(value < current->value)
			nodep = ¤t->left;
		else
			nodep = ¤t->right;
	}

	current = (Node *)malloc(sizeof(Node));
	assert(current != NULL);
	current->left = NULL;
	current->right = NULL;
	current->value = value;	
	*nodep = current;
}

//查找
TREE_TYPE * find(TREE_TYPE value)
{
	Node * current;

	current = root;

	while(current != NULL && current->value != value)
	{
		if(value < current->value)
			current = current->left;
		else
			current = current->right;
	}

	if(current != NULL)
		return ¤t->value;
	else
		return NULL;
}



static void do_pre_order_traverse(Node * node)
{
	if(node == NULL)
		return ;

	printf("%d\n",node->value);

	do_pre_order_traverse(node->left);
	do_pre_order_traverse(node->right);
}


static void do_in_order_traverse(Node * node)
{
	if(node == NULL)
		return ;

	do_in_order_traverse(node->left);
	printf("%d\n",node->value);
	do_in_order_traverse(node->right);
}


static void do_post_order_traverse(Node * node)
{
	if(node == NULL)
		return ;

	do_post_order_traverse(node->left);
	do_post_order_traverse(node->right);
	printf("%d\n",node->value);
}

//前序遍历
void pre_order_traverse(void )
{
	do_pre_order_traverse(root);
}

//中序遍历
void in_order_travserse(void )
{
	do_in_order_traverse(root);
}

//后序遍历
void post_order_travserse(void )
{
	do_post_order_traverse(root);
}


static void do_post_order_traverse_for_free(Node * node)
{
	if(node == NULL)
		return;
	do_post_order_traverse_for_free(node->left);
	do_post_order_traverse_for_free(node->right);
	free(node);
}
//释放“二叉搜索树”的内存
void destroy_tree()
{
	do_post_order_traverse_for_free(root);
}


static TREE_TYPE get_max(Node * node)
{
	Node * current, * tmp_node;

	while((current = node) != NULL)
	{
		tmp_node = current;
		node = node->right;
	}

	return tmp_node->value;
}


static Node ** find_node(TREE_TYPE value)
{
	Node ** nodep;
	Node * current;

	nodep = &root;

	while((current = *nodep) != NULL && current->value != value)
	{
		if(value < current->value)
			nodep = ¤t->left;
		else
			nodep = ¤t->right;
	}

	if(current != NULL)
		return nodep;
	else 
		return NULL;
}


//删除某个值,若不存在就终止程序运行。
void delete_value(TREE_TYPE value)
{
	Node ** targetNode = find_node(value); 
	if (!targetNode)
	{
		printf(" no value found in the tree!\n");
		exit(1);
	}

	if((*targetNode)->left == NULL && (*targetNode)->right == NULL){
		free(*targetNode);
		*targetNode = NULL;
	}else if((*targetNode)->left == NULL || (*targetNode)->right == NULL){
		Node * tmp_node = *targetNode;

		if((*targetNode)->left != NULL){			
			*targetNode = (*targetNode)->left;			
		}else{
			*targetNode = (*targetNode)->right;
		}
		free(tmp_node);
	}else{
		int max_value = get_max((*targetNode)->left);
		delete_value(max_value);
		(*targetNode)->value = max_value;
	}
}

测试无误。


删除操作自己写得很乱,在这里贴上《C和指针》一书习题17.10的参考答案,《C和指针》一书习题答案见资源中-http://download.csdn.net/detail/scalerzhangjie/6013359。

/*
** Delete a node from a linked binary search tree
*/
void
delete_good( TREE_TYPE value )
{
	TreeNode *current;
	TreeNode **link;
	/*
	** First, locate the value. It must exist in the tree or this routine
	** will abort the program.
	*/
	link = &tree;
	while( (current = *link) != NULL && value != current–>value ){
		if( value < current–>value )
			link = ¤t–>left;
		else
			link = ¤t–>right;
	}
	assert( current != NULL );
	/*
	** We’ve found the value. See how many children it has.
	*/
	if( current–>left == NULL && current–>right == NULL ){
		/*
		** It is a leaf; no children to worry about!
		*/
		*link = NULL;
		free( current );
	}
	else if( current–>left == NULL || current–>right == NULL ){
		/*
		** The node has only one child, so the parent will simply
		** inherit it.
		*/
		if( current–>left != NULL )
			*link = current–>left;
		else
			*link = current–>right;
		free( current );
	}
	else {
		/*
		** The node has two children! Replace its value with the
		** largest value from its left subtree, and then delete that
		** node instead.
		*/
		TreeNode *this_child;
		TreeNode *next_child;
		this_child = current–>left;
		next_child = this_child–>right;
		while( next_child != NULL ){
			this_child = next_child;
			next_child = this_child–>right;
		}
		/*
		** Delete the child and replace the current value with
		** this_child’s value.
		*/
		value = this_child–>value;
		delete( value );
		current–>value = value;
	}
}




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

coffee_baba

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值