代码如下:
void Del_X_3(LinkList &L,ElemType x) { LNode *p; if(L==NULL) return ; if(L->data==x) { p=L; L=L->next; free(p); Del_X_3(L,x);//位置1 }else { Del_X_3(L->next,x);//位置2 } }
我们的疑点是递归操作中好像只进行了删除操作,而没有改变被删除结点的前驱,使其指向被删除结点的下一个结点。
例如p指向要删除的结点,q为该结点的前驱,那么要实现删除结点,代码为:q->next=p->next;
理解说明:
1、函数的递归调用时,总会再调用前将现有函数中的变量压入堆栈进行保存。
2、例如为了简便起见,我们定义一个单链表,且只含有三个数据:1,5,6.我们要删除的数据 为5。函数在执行时,走到位置2处,将L->next作为参数,传递到了函数Del_X_3中,这里传入的参数是引用类型,进入函数体后:
p=L; L=L->next; //这里L为调用该函数的外层L->next,故这里实现了L->next=L-next->next,如下图 free(p); Del_X_3(L,x);

为了更好的理解编写工程运行一下,主函数如下:
(我们可以进行单步调试,看一下程序的执行流程,这里略)
typedef int ElemType ; #include "lianbiaohead.h" #include "lianbiaoname.h" #include "lianbiaostruct.h" void Del_X_3(LinkList &L,ElemType x) { LNode *p; if(L==NULL) return ; if(L->data==x) { p=L; L=L->next; free(p); Del_X_3(L,x); }else { Del_X_3(L->next,x); } } int main() { const int NUM=3; ElemType a[NUM]={1,5,6}; LinkList L; InitList(&L); LinkList p=L; LNode* p1=L; for(int i=0;i<NUM;i++) { LinkList s=(LinkList)malloc(sizeof(LNode)); s->data=a[i]; ListInsert_L(L,p,s); p=p->next; } cout<<"删除之前"<<endl; ListTraverse(L); Del_X_3(L->next,5); cout<<"删除之后"<<endl; ListTraverse(L); return 0; }
执行效果如下: