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