链表第一个结点怎么删除不掉

时间:2022-05-16 19:10:43
写了个删除节点的函数
发现当不满足条件的时候
头节点没有删除掉
其他的都删掉了
函数如下所示

void del(Linklist *p,Linklist *head)
{
Linklist *q;

q=head;

if(p!=head)//head为头结点,含有第一个值,判断p是否是第一个节点
    {

     while(q!=NULL && q->nextl!=p)
                  q=q->next;

     q->next=p->next;
     p=p->next;

    }
else//如果是第一个节点
    {

     head=head->next;
     p=head;

     }
}
到底哪里出问题了
谢谢

23 个解决方案

#1


else//如果是第一个节点
    {

    p=head;
    head->next = NULL;

    } 

#2


ls的兄弟
不行啊

#3


?为啥不行,你咋检查删除的?

#4


我没改之前 
我运行程序后,不满足条件的和头结点会输出

但是改了之后,运行后,直接报错 说什么内存不读

#5


else//如果是第一个节点
{
  p=head;
  head = NULL;


再试试。

#6


还是不行哦
跟我没修改时是一样的

#7


贴出你程序的完整代码
包括主程序
我怎么觉得你没有c++的引用 没有返回 没有用二级指针怎么就改变了链表
我想看看你的程序 麻烦楼主贴出来 
在线等

#8


那应该是你的其他代码有问题。

#9


引用 7 楼 huiguixian 的回复:
贴出你程序的完整代码
包括主程序
我怎么觉得你没有c++的引用 没有返回 没有用二级指针怎么就改变了链表
我想看看你的程序 麻烦楼主贴出来
在线等

就是这个函数起作用了啊
两个参数 一个是要删除的节点 在一个是 链表的头

#10


可是这是值传递啊 
应该不会改变的吧 
我是新手 我不太理解
所以想看一下你全部代码 分析一下
麻烦楼主贴出来

#11


你看看指针 那一章的相关内容
你就明白了

#12


我想看你的Linklist的声明。看上去你企图通过值传递来修改实参内容,这是行不通的。

#13


typedef struct node{

int b[10];
char a;
int num;
struct node *next;

}Linklist; 

#14


引用 12 楼 the_face 的回复:
我想看你的Linklist的声明。看上去你企图通过值传递来修改实参内容,这是行不通的。

在函数中 修改
指针的地址 不行吗

#15


看看楼主的源代码,这样只能看一部分,不知道其他的实现。

#16


head的地址变不了  它后面的可以变 
删除头节点 用返回值为头节点 试试

#17


看来楼主误解了 我说的值传递就是指指针的值传递
除非你对用二级指针 把原来头指针的地址传过来
否则你是无法改变的
指针传递依旧是值传递!

#18


链表的头结点不都是不存储值的吗?只是为了统一处理整个链表而不用为了第一个结点而去单独处理而设立的吗?

#19


17#的是正确的,要向改变头指针的指向的话就要再建立一个指针指向头指针,然后就可以修改了

#20


根据大家的建议,我把代码进行了修改,
在del函数中,返回了应删除节点后面的
一个节点,但是当要删除的是头结点时
还是没有删除头结点

        printf("请输入最小的值: ");
scanf("%d",&minsup);

l1=headl;

while (l1->a!=NULL)
{
if(minsup>l1->num)
{

printf("属性 %c 的值小于最小值,故删除\n",l1->a);
l1=del(l1,headl);
}
else
l1=l1->nextl;

}

Linklist *del(Linklist *p,Linklist *head)
{
Linklist *q;
q=head;
if(p!=head)
{
while(q!=NULL && q->nextl!=p)
q=q->next;
q->next=p->nextl;
p=p->next;
return(p);
}
else
{
head=p->nextl;
p=head;
return(p);
}

}

当 指针返回后 
令 l1=head;
    printf("%c",l1->a);
    不满足要求的头结点 还是没有删除掉

#21


你单步进去看一下啊。。。

#22


问题很明显
else//如果是第一个节点
    {

    head=head->next;
    p=head;

    } 


head=head->next;
在删除这个函数中
head作为拷贝,一个局部变量存在,这样head = head->next 实际上只是将head->next的地址赋给这个临时变量而已,当函数返回后,这个值就是垃圾了,你可以使用指针的指针的来操作
void del(Linklist *p,Linklist *head) 
改为void del(Linklist *p,Linklist **head)
然后else//如果是第一个节点
    {

    head=head->next;
    p=head;

    } 
改为
else
{
    *head = (*head)->next;
    p = *head;
    free(p);
    p = NULL;
}
 
其余的部分你应该会改。

#23


楼上的想法应该是正确的,楼主试试看

#1


else//如果是第一个节点
    {

    p=head;
    head->next = NULL;

    } 

#2


ls的兄弟
不行啊

#3


?为啥不行,你咋检查删除的?

#4


我没改之前 
我运行程序后,不满足条件的和头结点会输出

但是改了之后,运行后,直接报错 说什么内存不读

#5


else//如果是第一个节点
{
  p=head;
  head = NULL;


再试试。

#6


还是不行哦
跟我没修改时是一样的

#7


贴出你程序的完整代码
包括主程序
我怎么觉得你没有c++的引用 没有返回 没有用二级指针怎么就改变了链表
我想看看你的程序 麻烦楼主贴出来 
在线等

#8


那应该是你的其他代码有问题。

#9


引用 7 楼 huiguixian 的回复:
贴出你程序的完整代码
包括主程序
我怎么觉得你没有c++的引用 没有返回 没有用二级指针怎么就改变了链表
我想看看你的程序 麻烦楼主贴出来
在线等

就是这个函数起作用了啊
两个参数 一个是要删除的节点 在一个是 链表的头

#10


可是这是值传递啊 
应该不会改变的吧 
我是新手 我不太理解
所以想看一下你全部代码 分析一下
麻烦楼主贴出来

#11


你看看指针 那一章的相关内容
你就明白了

#12


我想看你的Linklist的声明。看上去你企图通过值传递来修改实参内容,这是行不通的。

#13


typedef struct node{

int b[10];
char a;
int num;
struct node *next;

}Linklist; 

#14


引用 12 楼 the_face 的回复:
我想看你的Linklist的声明。看上去你企图通过值传递来修改实参内容,这是行不通的。

在函数中 修改
指针的地址 不行吗

#15


看看楼主的源代码,这样只能看一部分,不知道其他的实现。

#16


head的地址变不了  它后面的可以变 
删除头节点 用返回值为头节点 试试

#17


看来楼主误解了 我说的值传递就是指指针的值传递
除非你对用二级指针 把原来头指针的地址传过来
否则你是无法改变的
指针传递依旧是值传递!

#18


链表的头结点不都是不存储值的吗?只是为了统一处理整个链表而不用为了第一个结点而去单独处理而设立的吗?

#19


17#的是正确的,要向改变头指针的指向的话就要再建立一个指针指向头指针,然后就可以修改了

#20


根据大家的建议,我把代码进行了修改,
在del函数中,返回了应删除节点后面的
一个节点,但是当要删除的是头结点时
还是没有删除头结点

        printf("请输入最小的值: ");
scanf("%d",&minsup);

l1=headl;

while (l1->a!=NULL)
{
if(minsup>l1->num)
{

printf("属性 %c 的值小于最小值,故删除\n",l1->a);
l1=del(l1,headl);
}
else
l1=l1->nextl;

}

Linklist *del(Linklist *p,Linklist *head)
{
Linklist *q;
q=head;
if(p!=head)
{
while(q!=NULL && q->nextl!=p)
q=q->next;
q->next=p->nextl;
p=p->next;
return(p);
}
else
{
head=p->nextl;
p=head;
return(p);
}

}

当 指针返回后 
令 l1=head;
    printf("%c",l1->a);
    不满足要求的头结点 还是没有删除掉

#21


你单步进去看一下啊。。。

#22


问题很明显
else//如果是第一个节点
    {

    head=head->next;
    p=head;

    } 


head=head->next;
在删除这个函数中
head作为拷贝,一个局部变量存在,这样head = head->next 实际上只是将head->next的地址赋给这个临时变量而已,当函数返回后,这个值就是垃圾了,你可以使用指针的指针的来操作
void del(Linklist *p,Linklist *head) 
改为void del(Linklist *p,Linklist **head)
然后else//如果是第一个节点
    {

    head=head->next;
    p=head;

    } 
改为
else
{
    *head = (*head)->next;
    p = *head;
    free(p);
    p = NULL;
}
 
其余的部分你应该会改。

#23


楼上的想法应该是正确的,楼主试试看