C语言实现 设计一个递归算法,删除不带头结点的单链表L中所有值为X的节点

本文详细解析了如何使用C语言实现单链表中删除特定值的所有节点的递归算法,对比C++引用功能,介绍避免链表断裂的双指针技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

C语言实现 设计一个递归算法,删除不带头结点的单链表L中所有值为X的节点

这个算法题是王道数据结构考研复习指导的题

书上面地源码是用C++实现的

void Del_X_3(Linklist& L, ElemType x)
{
	//递归实现在单链表L中删除值为X的节点
	LNode* p;		//定义待删除的节点
	if (L == NULL)
		return;		//递归出口
	if (L->data == x)		//若L所直接点值为x
	{
		p = L;
		L = L->next;		//删除*L,并让L只想下一个节点
		free(p);
		Del_X_3(L, x);		//递归调用
	}
	else		//若L所直接点值不为x
	{
		Del_X_3(L->next, x);	//递归调用
	}
}

这个最巧妙的是C++里面的引用功能&,所以并不会造成链表断裂
但是C语言中没有引用,如果直接把C++代码翻译成C语言代码是这样子的

void DeleteElement(SqNode * L, int Value)
{
	SqNode *s;//定义待删除的节点
	if (L == NULL)
	{
		return;//递归出口
	}
	if (L->data == Value)////若L所直接点值为Value
	{
		s = L;
		L = L->Next;//删除*L,并让L只想下一个节点   ``注意这里会造成链表断裂 ``
		free(s);
		DeleteElement(L, Value);//递归调用
	}
	else
	{
		DeleteElement(L->Next, Value);//递归调用

	}
}

这里会造成链表断裂例如删除 1 2 3 4 中的3 经过free之后,3这个内存空间会进行释放,但是他的后继节点也相应的丢失,全部变成野指针!

正确的做法是利用C语言的双指针,指向指针的指针

正确代码

结构体

typedef struct SqNode {
	int data;
    struct	SqNode* Next;
}SqNode,*SqList;
SqList DeleteElement(SqList *L, int Value)
{
//SqList是结构体指针
	SqList s;
	if (*L == NULL)
	{
		return;
	}
	if ((*L)->data == Value )
	{
		s = *L;
		*L = (*L)->Next;   //利用双指针就不会造成链表断裂,是地址只想地址,这样就可以了
		free(s);
	    DeleteElement(L,Value);
	}
	else
	{
		DeleteElement(&((*L)->Next), Value);
	}
}

输入样例

1 2 3 4 3 删除3
在这里插入图片描述

完整代码

#include<stdio.h>

typedef struct SqNode {
	int data;
    struct	SqNode* Next;
}SqNode,*SqList;



SqList CreateList(SqList L)
{
	L = (SqList)malloc(sizeof(SqNode));
	SqList s;
	SqList r;
	int Value=0;
	printf("请输入您需要创建的链表\n");
	scanf_s("%d", &Value);
	getchar();
	L->data = Value;
	L->Next = NULL;
	r = L;
	scanf_s("%d", &Value);
	getchar();
	while (Value!=999)
	{
		s = (SqList)malloc(sizeof(SqNode));
		s->data = Value;
		s->Next = r->Next;
		r->Next = s;
		r = s;
		scanf_s("%d", &Value);
		getchar();
	}
	return L;

}
//创建链表

SqList DeleteElement(SqList *L, int Value)
{
	SqList s;
	if (*L == NULL)
	{
		return;
	}
	if ((*L)->data == Value )
	{
		s = *L;
		*L = (*L)->Next;
		free(s);
	    DeleteElement(L,Value);
	}
	else
	{
		DeleteElement(&((*L)->Next), Value);
		
	}
}





void PrintList(SqList L)
{
	SqList s;
	s = L;
	while (s != NULL)
	{
		printf("%d\t", s->data);
		s = s->Next;
	}
	printf("\n");
}


void main()
{
	SqList L=NULL;
	L=CreateList(L);
	PrintList(L);
	DeleteElement(&L, 3);
 	PrintList(L);
}

感谢colorfulshark博主给的提示

欢迎大家在品论去赐教

评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

~搬~运~工~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值