这是一个单链表的递归问题
问:一个带头节点的单链表,要删除所有值为X的节点,并释放空间,X不唯一(用递归实现)这是我的代码:
void Del_X(LinkList L,int x){
LNode *p;
if(L==NULL)
return;
if(L->data==x){
p=L;
L=L->next;
free(p);
Del_X(L,x);
}
else{
Del_X(L->next,x);
}
}
感觉直接free(p)会断链,实际测试也确实有问题,请问问题在哪呢?能怎么改进?{:10_254:} 还是传参数传错了,要传指向指针的指针。
void Del_X(LinkList * L,int x)
{
LNode *p;
if(*L==NULL)
return;
if((*L)->data==x)
{
p=*L;
*L=(*L)->next;
free(p);
Del_X(L,x);
}
else
{
Del_X(&((*L)->next),x);
}
} 本帖最后由 sunrise085 于 2020-8-10 22:59 编辑
对于有头结点的链表,你需要考虑头结点;
此外删除一个节点的时候,需要把后面的节点连接到前面的节点上,然后才能删除中间的节点。
看下图,L不是头结点的时候也是一样的
void Del_X(LinkList L,int x){
LNode *p;
if(L->next==NULL)// 有头结点,所以需要判断的是下一个节点
return;
if(L->next->data==x){//头结点是没有数据的,需要判断的是下一个节点的data,然后删除的也是下一个节点
p=L->next;
L->next=L->next->next;//你之前的写法,删除一个节点,并没有把链表连接起来
free(p);
Del_X(L->next,x);
}
else{
Del_X(L->next,x);
}
} 楼上说得对 sunrise085 发表于 2020-8-10 22:57
对于有头结点的链表,你需要考虑头结点;
此外删除一个节点的时候,需要把后面的节点连接到前面的节点上, ...
运行了一下,好像会有问题,且无法输出
大神再试验一下{:10_254:}
我真的搞不懂啊{:10_250:} sunrise085 发表于 2020-8-10 22:57
对于有头结点的链表,你需要考虑头结点;
此外删除一个节点的时候,需要把后面的节点连接到前面的节点上, ...
static void Print(LinkList L){
while(L->next!=NULL){
L=L->next;
printf("%d\n",L->data);
}
return;
}
这是我的输出函数 另外,为什么要用递归呢?函数参数传递没搞懂哦。用普通循环结构你的写法就没问题 xieglt 发表于 2020-8-11 09:27
另外,为什么要用递归呢?函数参数传递没搞懂哦。用普通循环结构你的写法就没问题
我知道循环可以,这不是做题嘛
xieglt 发表于 2020-8-11 09:27
另外,为什么要用递归呢?函数参数传递没搞懂哦。用普通循环结构你的写法就没问题
指针的指针感觉有点不好懂 jsaac 发表于 2020-8-11 09:28
我知道循环可以,这不是做题嘛
参数传错了,要传递指针的指针! xieglt 发表于 2020-8-11 09:30
参数传错了,要传递指针的指针!
实测可行 int main(void)
{
//定义了一个链表头,这是一个指针变量,它的值指向一个地址
//编译器会在栈里分配一段内存来存储* Head,假设这段内存起始地址为0x12345
Lnode * Head = NULL;
//初始化链表,假设Head的值 = 0X54321;
//那么,0x54321就是它指向的地址
//而0x12345则是这个指针变量的地址,也就是指针的指针
Head =InitList();
//调用删除节点函数
//传递指针的值,函数将在栈里分配一段内存,假设这段内存的起始地址为0x12350
//编译器将把0x54321复制到0x12350这段内存里并传到函数里去。
//如果0x54321指向的Data == X ,那么free(0x54321)是没有问题的
//问题出在L= L->next这一句,L的地址是0X12350,这一句相当于把L->next复制到0x12350;
//而不是复制到Head的地址0X12345,所以Head的值并没有改变。
Del_X(Head,X)
//如果是传递指针的指针就不一样
//同样函数将在栈里分配一段内存,假设这段内存的起始地址为0x12350
//编译器则将把0x12345复制到0x12350这段内存里并传到函数里去。
//*L=(*L)->next,就是把(*L)->next复制到0x12345里头,Head的值才得以改变
Del_X(&Head,X)
return 0;
}
很拗口,比较难理解,多学多练,慢慢总会理解的。 xieglt 发表于 2020-8-11 09:55
int main(void)
{
//定义了一个链表头,这是一个指针变量,它的值指向一个地址
另外,我想知道直接free而并没有连接删除节点前后的两个链表,为什么不会断链呢
页:
[1]