谭浩强c语言第五版第9章的习题10,本文主题如下:
1.对参考答案代码进行解析和勘误;
2.提出一种更准确的算法(原来的链表可为无序),给出代码;
1.对参考答案代码进行解析和勘误:
首先给出参考答案源代码:
#include <stdio.h>
#include <stdlib.h>
struct Student
{
long num;
int score;
struct Student *next;
};
struct Student lista, listb;
int n, sum = 0;
int main()
{
struct Student *creat();
struct Student *insert(struct Student *, struct Student *);
void print(struct Student *);
struct Student *ahead, *bhead, *abh;
printf("input list a:\n");
ahead = creat();
sum = sum + n;
printf("input list b:\n");
bhead = creat();
sum = sum + n;
abh = insert(ahead, bhead);
print(abh);
return 0;
}
struct Student *creat()
{
struct Student *p1, *p2, *head;
n = 0;
p1 = p2 = (struct Student *)malloc(sizeof(struct Student));
printf("input number & scores of student:\n");
printf("if number is 0,stop inputing.\n");
scanf_s("%ld %d", &p1->num, &p1->score);
head = NULL;
while (p1->num!=0)
{
n = n + 1;
if (n == 1)
head = p1;
else
p2->next = p1;
p2 = p1;
p1 = (struct Student *)malloc(sizeof(struct Student));
scanf_s("%ld %d", &p1->num, &p1->score);
}
p2->next = NULL;
return head;
}
struct Student *insert(struct Student *ah, struct Student *bh)
{
struct Student *pa1, *pa2, *pb1, *pb2;
pa2 = pa1 = ah;
pb2 = pb1 = bh;
do
{
while ((pb1->num>pa1->num)&&(pa1->next!=NULL))
{
pa2 = pa1;
pa1 = pa1->next;
}
if (pb1->num <= pa1->num)
{
if (ah == pa1)
ah = pb1;
else
pa2->next = pb1;
pb1 = pb1->next;
pb2->next = pa1;
pa2 = pb2;
pb2 = pb1;
}
} while ((pa1->next != NULL) || (pa1 == NULL && pb1 != NULL));
if ((pb1 != NULL) && (pb1->num > pa1->num) && (pa1->next == NULL))
pa1->next = pb1;
return(ah);
}
void print(struct Student *head)
{
struct Student *p;
printf("There are %d records:\n", sum);
p = head;
if(p!=NULL)
do
{
printf("%ld %d\n", p->num, p->score);
p = p->next;
} while (p != NULL);
}
主函数中:调用创建链表函数creat()建立了a,b链表(在命令行窗口输入链表内容),然后调用函数insert(),将a,b的头指针ahead,bhead传递给insert()函数,在insert()函数中完成合并并排序,最后返回合并后的链表的头指针abh,最后调用函数print(),打印输出合并后的链表。
insert()函数中:
struct Student *pa1, *pa2, *pb1, *pb2;
pa2 = pa1 = ah;
pb2 = pb1 = bh;
定义Student结构体变量类型的指针,pa1,pa2,pb1,pb2,将链表a的头指针赋给pa1,pa2,将链表b的头指针赋给pb1,pb2。在程序中pa1,pa2指向链表a的节点,pb1,pb2指向链表b的节点。
do
{
while ((pb1->num>pa1->num)&&(pa1->next!=NULL))
{
pa2 = pa1;
pa1 = pa1->next;
}
if (pb1->num <= pa1->num)
{
if (ah == pa1)
ah = pb1;
else
pa2->next = pb1;
pb1 = pb1->next;
pb2->next = pa1;
pa2 = pb2;
pb2 = pb1;
}
} while ((pa1->next != NULL) || (pa1 == NULL && pb1 != NUL