C语言。有两个链表a和b,从a链表中删去与b链表中有相同学号的那些结点!

2025-03-06 02:39:55
推荐回答(1个)
回答1:

/*
有两个链表a和b,从a链表中删去与b链表中有相同学号的那些结点!
*/
#include
#include
#include

struct student
{
int num;
char name[10];
struct student *next;
};

int main()
{
void print(struct student *head);
struct student *creat();
struct student *solve(struct student *head_a,struct student *head_b);
struct student *head,*head_a,*head_b;
printf("********初始化链表A********\n");
head_a=creat();
printf("********输出链表A********\n");
print(head_a);

printf("********初始化链表B********\n");
head_b=creat();
printf("********输出链表B********\n");
print(head_b);

printf("********从a链表中删去与b链表中有相同学号的那些结点********\n");
head=solve(head_a,head_b);

print(head);

return 0;
}

struct student *creat()
{
struct student *head,*p,*p1;

/*
【1】
注意 creat 函数中认为链表是有一个表头节点的,也就是链表的第一节点是 head->next,
而不是 head。

而下面的 solve 函数和 print 函数都认为链表是没有表头节点的,也就是他们认为链表的
第一个节点是:head 而不是 head->next 。

这是你程序出错的原因所在。

改正:为了方便,把链表改成不带头节点的,也就是第一个节点为:head
*/
p = p1=(struct student *)malloc(sizeof(struct student));
head = NULL;

printf("请输入学生学号和姓名(输入学号0和姓名0停止接收数据):");
scanf("%d%s",&p->num,&p->name);
while(!(p->num == 0 && strcmp(p->name,"0")==0))
{
if(head == NULL)
{
head = p;
p1=head;
p=(struct student *)malloc(sizeof(struct student));
}
else
{
p1->next=p;
p1=p;
p=(struct student *)malloc(sizeof(struct student));
}

printf("请输入学生学号和姓名(输入学号0和姓名0停止接收数据):");
scanf("%d%s",&p->num,&p->name);
}
p1->next=NULL;
return head;
}

struct student *solve(struct student *head_a,struct student *head_b)
{
struct student *p,*p1,*t;
p=p1=head_a;

if(head_b == NULL)
{
return head_a;
}

while(p!=NULL)
{
t=head_b;
/*
【2】
while(t->next!=NULL && (t->num!=p->num))
这里有个问题:
a)你不能保证 head_b 不是一个空链表,也就可能是 t == NULL 的情况。
这时引用 t->next 会出错 !!!

改正: 在一开始就加上 head_b == NULL 的判断
*/

while(t->next!=NULL && (t->num!=p->num))
{
t=t->next;
}

if(t->num==p->num)
{
if(p==head_a)
{
head_a=head_a->next;
p1=p=head_a;
}
else
{
p1->next=p->next;
p=p->next;
}
}
else
{
p1=p;
p=p->next;
}
}
return head_a;
}

void print(struct student *head)
{
struct student *p;
/*
这个错误太明显了,指针 p 没有赋初值

改正:p = head;
*/
p = head;
while(p!=NULL)
{
printf("%d %s\n",p->num,p->name);
p=p->next;
}
}

/*
测试数据:
1 a
2 b
3 c
4 d
5 e
6 f
7 g
0 0
2 b
5 e
0 0

输出结果:
********初始化链表A********
请输入学生学号和姓名(输入学号0和姓名0停止接收数据):1 a
请输入学生学号和姓名(输入学号0和姓名0停止接收数据):2 b
请输入学生学号和姓名(输入学号0和姓名0停止接收数据):3 c
请输入学生学号和姓名(输入学号0和姓名0停止接收数据):4 d
请输入学生学号和姓名(输入学号0和姓名0停止接收数据):5 e
请输入学生学号和姓名(输入学号0和姓名0停止接收数据):6 f
请输入学生学号和姓名(输入学号0和姓名0停止接收数据):7 g
请输入学生学号和姓名(输入学号0和姓名0停止接收数据):0 0
********输出链表A********
1 a
2 b
3 c
4 d
5 e
6 f
7 g
********初始化链表B********
请输入学生学号和姓名(输入学号0和姓名0停止接收数据):2 b
请输入学生学号和姓名(输入学号0和姓名0停止接收数据):5 e
请输入学生学号和姓名(输入学号0和姓名0停止接收数据):0 0
********输出链表B********
2 b
5 e
********从a链表中删去与b链表中有相同学号的那些结点********
1 a
3 c
4 d
6 f
7 g
*/
这样可以么?