题目
设计一个递归算法,删除不带头结点的单链表L中所有值为x的结点。
代码实现
void Del_X(Linklist &L,ElemType x ){
LNode *p; //用p来存储待删除的结点的指针
if(L==NULL) //递归的出口
return;
if(L->data==x) //找到待删除结点
{
p=L; //删除*L结点,并将L指向下一结点
L=L->next;
free(p);
Del_X(L,x); //递归调用
}
else{
Del_X(L->next,x); //若结点的值不为x,则继续递归调用
}
}
对于“不断链”的解释
设有不带头结点的单链表,已知第一个结点的指针L:
正常情况下单链表删除值为x结点的方法应该是:
p=L->next;
L->next=p->next;
free(p);
结合上例和代码,可能会让人感觉最上面的递归代码好像 少了把待删除结点 *p前后的结点*L,*q连接起来的操作,即让人感觉 “断链” 了。
下面对删除结点这一过程进行分析:第一次执行Del_X(L,x),由于结点值为a,执行Del_X(L->next,x);
此时的 L->next就是值为x结点的指针,进入到递归函数中,由于值为x,因此执行
p=L;
L=L->next;
free(p);
Del_X(L,x);
由于此次递归输入的形参的实际值是L->next,所以在这次递归中的函数出现的 L实际上是L->next,所以L=L->next 实际上是L->next=L->next->next,即越过了 *p结点将 *L, *q结点连上了,再把 *p结点删除。
所以说链表没断。。