将两个链表(可为乱序)合并成一个有序链表(C语言实现)

这篇博客主要解析了谭浩强C语言第五版第9章习题10,探讨了如何正确合并两个(可能是无序的)链表成一个有序链表。首先指出了参考答案代码中的错误,接着提出了一种更优的算法,通过循环遍历和比较两个链表的节点,将较小节点插入新链表,以保证合并后链表的有序性。博主详细解释了代码逻辑,包括循环判断条件的修正和合并排序过程。

谭浩强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
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值