今年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;
}
}