单链表删除第一个节点时出错!

tianxingzhe37 2010-03-13 06:57:21
删除其它位置的节点没错,但删除第一个节点是出错!

#include <stdio.h>
#include <stdlib.h>

typedef int datatype;
typedef struct link_node
{
datatype info;
struct link_node * next;
}node;

node * init_link_list()//初始化单链表
{
return NULL;
}

void print_link_list(node *head)//打印单链表各个节点值
{
node *p;
p=head;
if(!p)
{
printf("link list is empty!\n");
exit(1);
}
else
{
printf("link list every value is :\n");
while(p)
{
printf("%5d",p->info);
p=p->next;
}
printf("\n");
}

}

node *find_num_link_list(node * head,datatype x)//查找值为x的节点
{
node *p;
p=head;
if(!p)
{
printf("link list is empty!\n");
exit(1);
}
while(p && p->info!=x)
p=p->next;
return p;
}

node *find_pos_link_list(node *head,int i)//查找第i个节点
{
int j=1;
node *p;
p=head;


if(i<1)
{
printf("there is no %d position!\n",i);
exit(1);
}
while(p && i!=j)
{
j++;
p=p->next;
}
return p;
}

node *insert_in_front_link_list(node *head,datatype x)//插入一个值为x的节点作为单链表的第一个节点
{
node *q;

q=(node*)malloc(sizeof(node));
q->info=x;
q->next=head;
head=q;
return head;
}

node *insert_x_after_y_link_list(node *head,datatype y,datatype x)//在值为y的节点后插入一个值为x的节点
{
node *p,*q;
p=find_num_link_list(head,y);
if(!p)
{
printf("con not find %d\n",y);
exit(1);
}

q=(node*)malloc(sizeof(node));
q->info=x;
q->next=p->next;
p->next=q;

return head;
}

node *insert_x_after_i_link_list(node *head,int i,datatype x)//在第i个节点后插入值为x的节点
{
node *p,*q;
p=find_pos_link_list(head,i);
if(!p)
{
printf("there is no %d position\n",i);
exit(1);
}

q=(node*)malloc(sizeof(node));
q->info=x;
q->next=p->next;
p->next=q;
return head;
}

node *delete_num_link_list(node *head,datatype x)//删除值为x的节点
{
node *pre=NULL,*p;

if(!head)
{
printf("link list is empty!\n");
exit(1);
}
p=head;
while(p && p->info!=x)
{
pre=p;
p=p->next;
}
if(!pre && p->info==x)
{
head=head->next;
}
else if(p!=NULL)
{
pre->next=p->next;
}
else
{
printf("error!\n");
exit(1);
}
free(p);
return head;
}

node * delete_pos_link_list(node * head,int i)//删除第i个节点
{
node *p,*q=NULL;

if(i==1)
{
p=head;
head=head->next;
}
else
{
p=find_pos_link_list(head,i);
if(!p)
{
printf("con not find %d\n",i);
exit(1);
}
else
{
q=find_pos_link_list(head,i-1);
q->next=p->next;
}
}
free(p);
return head;

}

int main()
{
node *list;
list=init_link_list();

list=insert_in_front_link_list(list,1);
list=insert_in_front_link_list(list,2);
list=insert_in_front_link_list(list,3);
list=insert_in_front_link_list(list,4);
list=insert_in_front_link_list(list,5);
list=insert_in_front_link_list(list,6);
print_link_list(list);

insert_x_after_y_link_list(list,1,9);
print_link_list(list);
insert_x_after_y_link_list(list,6,59);
print_link_list(list);

insert_x_after_i_link_list(list,3,100);
print_link_list(list);
insert_x_after_i_link_list(list,7,220);
print_link_list(list);

delete_num_link_list(list,100);
print_link_list(list);

delete_pos_link_list(list,5);
print_link_list(list);
delete_pos_link_list(list,1);
print_link_list(list);
return 0;
}
...全文
262 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
ouzhf 2010-03-14
  • 打赏
  • 举报
回复
因为你删除第一个节点的话,在main函数中head的值已经被你释放了,但是你又没有把它的值传回来,改为引用调用之后,就不需要这么麻烦了。或者如5楼所说的也可以。
ouzhf 2010-03-14
  • 打赏
  • 举报
回复

void delete_pos_link_list(node *& head,int i)//ɾ³ýµÚi¸ö½Úµã
{
node *p,*q=NULL;

if(i==1)
{
p=head;
head=head->next;
}
else
{
p=find_pos_link_list(head,i);
if(!p)
{
printf("con not find %d\n",i);
exit(1);
}
else
{
q=find_pos_link_list(head,i-1);
q->next=p->next;
}
}
free(p);
// return head;

}

改用传指针引用,这样就可以啦
tianxingzhe37 2010-03-14
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 refreever 的回复:]
list=delete_pos_link_list(list,1); //改成这样吧,你删除第一个节点时,原先传入的list的指向没有改变,
[/Quote]
node *list,list是一个结构体类型的指针,指向的是单链表的第一个节点。当删除第一个节点时,删除成功,头指针改变,返回的是指向第二个节点的指针,我当时并没有用list=delete_pos_link_list(list,1); 来接受这个指针,当打印节点值时,由于第一个节点已被删除,但指针仍然指向那个删除的节点,当然就显示出错信息,即访问的内存不能读...



tianxingzhe37 2010-03-14
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 a7182388 的回复:]
我看了一下,没看明白,
还有,你说的第一个结点指的是head结点嘛?还是head后的第一个结点!
一般来说链表都有一个头结点,且头结点的数据域都不赋值!
你的head的数据域有值吗?head是你的头结点?
不好意思,我没打弄明白!
[/Quote]
你说的是带头结点的单链表,我这个只是单链表,head是一个指向单链表第一个节点的指针,也就是头指针。
a6324789 2010-03-14
  • 打赏
  • 举报
回复
在删除第一个有值节点的时候,链表必须借助首元节点——即数据域为空的头结点head.楼主仔细想想。
renzhewh 2010-03-13
  • 打赏
  • 举报
回复
没注意lz用的是返回值,既然这样,建议删除操作使用递归,形式上更为简洁
linxingyu404 2010-03-13
  • 打赏
  • 举报
回复
楼上正解,你前面的插入的时候都有=号的,为什么到删除的时候就没了。
reFreever 2010-03-13
  • 打赏
  • 举报
回复
list=delete_pos_link_list(list,1); //改成这样吧,你删除第一个节点时,原先传入的list的指向没有改变,
a7182388 2010-03-13
  • 打赏
  • 举报
回复
我看了一下,没看明白,
还有,你说的第一个结点指的是head结点嘛?还是head后的第一个结点!
一般来说链表都有一个头结点,且头结点的数据域都不赋值!
你的head的数据域有值吗?head是你的头结点?
不好意思,我没打弄明白!
tianxingzhe37 2010-03-13
  • 打赏
  • 举报
回复
不是这样改吧,函数都能运行啊,只是i==1时有问题。
renzhewh 2010-03-13
  • 打赏
  • 举报
回复
node *insert_in_front_link_list(node *head,datatype x)//插入一个值为x的节点作为单链表的第一个节点
{
node *q;

q=(node*)malloc(sizeof(node));
q->info=x;
q->next=head;
head=q;
return head;
}
参数node *head 中的head 应为 node ** ,在C语言中参数为传值调用。
函数中的实现做相应的修改即可。
tianxingzhe37 2010-03-13
  • 打赏
  • 举报
回复
急急急急急急!!!

69,369

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧