废话不说,直接上代码。
searchtree Delete(int x,searchtree t)
{
position tmp;
if(t==NULL)
return 0;//就先这么写吧
else if(x==t->element )
{
if(t->left &&t->right )
{
t->element =findmin (t->right)->element ;
t->right=Delete (t->element ,t->right );
}
else if(t->left ==NULL)//没有儿子的情况也包含了,因为t->right 为NULL
{
tmp=t;
t=t->right ;
free(tmp);
}
else
{
tmp=t;
t=t->left;
free(tmp);
}
}
else if(x>t->element )
t->right =Delete (x,t->right );
else
t->left=Delete (x,t->right );
return t;
}
这是一个删除二叉查找树的例子,非常常见。
之前对递归一直处于浑浑噩噩的状态,半知半解。后来突然就恍然大悟了。一点心得如下:
首先是读懂一个递归
这个很多经典书籍里讲过,用归纳法即可,在此不做赘述。然后是会写一个递归
1.首先得把几个基准情况写出
if(t==NULL);//节点为空
(x==t->element );//找到
(x>t->element );//大于
(x<t->element );//小于
2.将每一步仔细分析
若为空返回;
找到了以后,分类讨论;
if(t->left &&t->right )
{
t->element =findmin (t->right)->element ;
t->right=Delete (t->element ,t->right );
}
else if(t->left ==NULL)//没有儿子的情况也包含了,因为t->right 为NULL
{
tmp=t;
t=t->right ;
free(tmp);
}
else
{
tmp=t;
t=t->left;
free(tmp);
}
若大于;
t->right =Delete (x,t->right );
对右子树做删除操作。
若小于;
t->left=Delete (x,t->right );
对左子树做删除操作。
其实关键在于不需要去追溯左右子树如何如何,最终都将是在一个节点上进行操作,也就是那几个基准情况。
保证基准情况正确,并且保证能朝着基准推进即可,因为递归四条基本法则第三条(来自数据结构与算法分析-c描述,weiss):设计法则的意义就是假设所有递归调用可以运行,其实在此与其说是“假设”,当接触递归之后你会发现,这里不如说是“隐含”。