C语言建一个链表输入学生学号,姓名,性别,年龄。然后输入一个年龄,若存在此年龄的学生,则删除该结点

#include<stdio.h>
#include<stdlib.h>
#define LEN sizeof(struct Student)
struct Student
{
int num;
char name[20];
char sex;
int age;
struct Student *next;
};
int main()
{
struct Student *p1,*p2,*head,*p;
int a;
printf("input students'num,name,sex,age:\n");
p=head=p2=p1=(struct Student*)malloc(LEN);
scanf("%d %s %c %d",&(p1->num),p1->name,&(p1->sex),&(p1->age));
while((p1->num )!= 0)
{
p1=(struct Student*)malloc(LEN);
scanf("%d %s %c %d", &(p1->num), p1->name, &(p1->sex), &(p1->age));
p2->next=p1;
p2=p1;
}
free(p2);
p2=NULL;

do
{
printf("%03d %s %c %d\n",p->num,p->name,p->sex,p->age);
p=p->next;
}while(p!=NULL);
printf("input a num:\n");
scanf("%d",&a);
p=head;
do
{
if(a==p->age)
{
if(p==head)
{
free(p);
head=p->next;

}
else if(p->next==NULL)
{
free(p);
p=NULL;
}
else
{
free(p);
p=p->next;
}
}
p=p->next;
}while(p!=NULL);
p=head;
if(head!=NULL)
{
do
{
printf("%03d %s %c %d\n",p->num,p->name,p->sex,p->age);
p=p->next;
}while(p!=NULL);
}
return 0;
}

单向链表进行删除插入操作没有双向的好操作。
你的代码都有同一个问题,就是先指向,后改变。但前面指向的内容是不会变的。
比如 a->next=b; b=NULL; 结果a->next并不会为NULL。
然后你还对free后的节点进行操作,这肯定是不行的。
根据你的代码我做了一些修改是可以满足你的要求的。有点绕。好好理解肯定对你有借鉴意义。如果还有什么疑问再沟通。
希望这个答案你能满意,给分哦!
代码如下:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define LEN sizeof(struct Student)
struct Student
{
int num;
char name[20];
char sex;
int age;
struct Student *next;
};
int main()
{
struct Student *p1,*p2,*head,*p;
int a;
printf("input students'num,name,sex,age:\n");
p=head=p2=p1=(struct Student*)malloc(LEN);
scanf("%d %s %c %d",&(p1->num),p1->name,&(p1->sex),&(p1->age));
while((p1->num )!= 0)
{
p1=(struct Student*)malloc(LEN);
memset(p1,0,LEN); // 清 空,这是一个好习惯。
scanf("%d %s %c %d", &(p1->num), p1->name, &(p1->sex), &(p1->age));
if(p1->num)
p2->next=p1;
p2=p1;
}
free(p2); //猜想这里是要删除最后一个节点,因为num==0的是代表输入结束,没有意思
p2=NULL; //这个没有任何意义

do
{
printf("%03d %s %c %d\n",p->num,p->name,p->sex,p->age);
p=p->next;
}while(p!=NULL);
printf("input a num:\n");
scanf("%d",&a);
p2=head;

do
{
p=p2->next;
if(a==p2->age)
{
if(p2==head)
{
free(head);
p2=head=p;
}
else
{
memcpy(p2,p,LEN); //这个有点意思,想想在这里为什么不再移动指针
free(p);
}
}
else
{
p2=p2->next;
}
}while(p!=NULL);
p=head;
if(head!=NULL)
{
do
{
printf("%03d %s %c %d\n",p->num,p->name,p->sex,p->age);
p=p->next;
}while(p!=NULL);
}
return 0;
}追问

貌似输入最后一个学生的年龄删除不了。。

追答

我知道有这个问题,这个可以自己调,因为你的do while()是以p==NULL结束,
所以在上面的if else 中里面各添加一个p=p2->next;就行了。因为那时候把p2移动了,p没有跟着移。

这都是逻辑问题。其实还有别的改法。
比如把 p=p2->next 放到最后 ,然后再放一个p=p2->next初始化在do的前面也应该是可以解决的。
也可以想想别的方法。

温馨提示:答案为网友推荐,仅供参考
相似回答