設計一個遞歸算法,刪除不帶頭結點的單鏈表L中所有值為x的結點


代碼如下:

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;
}

執行效果如下:






免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM