最近在学习单链表的操作,增删查改这些,自己改善了一下代码,感觉其他的都没问题,就是删除函数这里有问题。我单独剔出来了
#include
#include
typedef struct link{
int value;
struct link *next;
}Link;
Link* init_list(void);//初始化
void display(Link *p);//链表输出
Link* del(Link *p,int location);//删除元素
int main()
{
int cut;
Link *q=init_list();
printf("初始化链表为\n");
display(q);
printf("请输入要删除的数的位置:\n");
scanf("%d",&cut);
del(q,cut);
display(q);
return 0;
}
Link* init_list(void)
{
re_input:
;
int x=0;
int mask=0,count=0;
Link* head=NULL;
Link *p=(Link*)malloc(sizeof(Link*));
head=p;
printf("请输入数据(输入-1结束)\n");
do
{
mask=scanf("%d",&x);
if(x!=-1&&mask!=0)
{
Link *a=(Link*)malloc(sizeof(Link*));
a->value=x;
a->next=NULL;
head->next=a;
head=head->next;
count++;
}
else if(x==-1&&count!=0){
break;
}
else
{
printf("输入中含有非法字符,请重新输入!\n");
fflush(stdin);
goto re_input;
}
}while(x!=-1);
return p;
}
/****************************************/
Link* del(Link *p,int location)
{
int i;
Link *temp=p;
Link *del=NULL;
for(i=1;iif(temp->next==NULL)
{
printf("删除位置无效!\n");
return p;
}
temp=temp->next;
}
del=temp->next;
temp->next=temp->next->next;
free(del);
return p;
}
/****************************************/
void display(Link *p)
{
Link* temp=p;
while(temp->next!=NULL)
{
temp=temp->next;
printf("%d ",temp->value);
}
printf("\n");
}
能帮忙看看该怎么改正吗
题主你好:
/*******************61*********************/
Link* del(Link *p,int location)
{
if(temp->next==NULL) //if判断放这里,不应该放在for循环里 表示对删除操作做合法性检查
{ // if(temp->next==NULL) 如果链表是空的,则删除操作不合法,后面没必要执行了,直接返回
printf("删除位置无效!\n");
return p;
}
int i;
Link *temp=p;
Link *del=NULL;
for(i=1;i<location;i++) {
temp=temp->next; //你说上面改成if (temp->next->next==NULL)就可以了只是巧合。因为如果你把原来的 if(temp->next==NULL) 放在这里
} //随着for循环的进行,temp在往后走,如果删除的是最后一个位置,会出现temp->next==NULL为真,就会出错返回
del=temp->next; //改成if (temp->next->next==NULL),删倒第二个结点也会为真。所以合法性检查应该放前面
temp->next=temp->next->next;
free(del);
return p;
}
/******************78**********************/
有帮助请点一下采纳谢谢,可以参考我写的单链表的文章,有图解
https://blog.csdn.net/qq_41796226/article/details/125980808?spm=1001.2014.3001.5502
可以重点看看删除函数的情况(61-78),其他的应该是好的。
自己试了试,好像67行if的条件改成
if (temp->next->next==NULL)
就可以了。
但是我有点理解不了
修改处见注释说明,供参考:
#include<stdio.h>
#include<stdlib.h>
typedef struct link{
int value;
struct link *next;
}Link;
Link* init_list(void);//初始化
void display(Link *p);//链表输出
void del(Link *p,int location);//删除元素 //Link* del(Link *p,int location);//删除元素
int main()
{
int cut;
Link *q=init_list();
printf("初始化链表为\n");
display(q);
printf("请输入要删除的数的位置:\n");
scanf("%d",&cut);
del(q,cut);
display(q);
return 0;
}
Link* init_list(void)
{
//re_input:
//;
int x=0;
int mask=0,count=0;
Link* head=NULL;
Link *p=(Link*)malloc(sizeof(Link*));
head=p;
printf("请输入数据(输入-1结束)\n");
do{
mask=scanf("%d",&x);
if(x!=-1 && mask==1) //x!=-1&&mask!=0 mask值有可能是 -1,这里用 mask != 0 判断不准确
{
Link *a=(Link*)malloc(sizeof(Link*));
a->value=x;
a->next=NULL;
head->next=a;
head = a;//head=head->next;修改 这句这样写没毛病,但修改下更直观
count++;
}
else if(x == - 1 && count!=0){
break;
}
else
{
printf("输入中含有非法字符,请重新输入数据(输入-1结束)\n");//修改
fflush(stdin);
//goto re_input; 输入错误,并不需要重新生成头结点,从 do 这里开始即可,重新输入 x.
} //所以这 goto 语句不必要。
}while(x!=-1);
return p;
}
/****************************************/
void del(Link *p,int location) //Link* del(Link *p,int location) 删除函数不需返回头指针。
{
int i;
Link *temp=p;
Link *del=NULL;
for(i=1;temp->next && i < location;i++){ //for(i=1;i<location;i++) 修改
//if(temp->next==NULL) 修改
//{
// printf("删除位置无效!\n"); 修改
// return p;
//}
temp=temp->next;
}
if (location <= 0 || temp->next == NULL){//修改
printf("删除位置无效!\n");
return;
}
del=temp->next;
temp->next=del->next; //temp->next=temp->next->next;这句这样写没毛病,修改更直观
free(del);
//return p; 修改
}
/****************************************/
void display(Link *p)
{
Link* temp=p;
while(temp->next!=NULL)
{
temp=temp->next;
printf("%d ",temp->value);
}
printf("\n");
}