代碼如下:
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;
}
執行效果如下:

