已有a,b两个链表,每个链表包含学号、成绩。要求合并两个链表,按学号升序排列。

70 篇文章 3 订阅
28 篇文章 3 订阅

已有a,b两个链表,每个链表包含学号、成绩。要求合并两个链表,按学号升序排列。

/*
已有a,b两个链表,每个链表包含学号、成绩。要求合并两个链表,按学号升序排列。 
*/
#include <stdio.h>
#include <malloc.h>//申请动态空间 
typedef struct node{
	int num;//学号
	float grade;//成绩
	struct node *next;
}node,*stu;

//初始化链表,长度有n结点
stu InitLink(stu a,int n,int flag)//flag 为1时说明需要手动赋值,为0说明不需要赋值 
{
	int size = sizeof(node);
	//构建头结点 不包含元素 
	stu head;
	head = (stu)malloc(size);
	head->grade = 0;
	head->num = 0;
	
	//构建保存数据的n个结点 
	stu p = head,q = NULL;
	for(int i = 0;i < n;i ++)
	{
		//创建一个结点 
		q = (stu)malloc(size);
		q->grade = 0;
		q->num = 0;
		q->next = NULL;
		//把结点加入链表(头插法)
		p->next = q;
		p = q;
		q = NULL; 
	}
	p = NULL;
	
	//flag为1说明手动赋值 
	if(flag == 1)
	{
		//控制台录入 数值,手动赋值(尾插法 构建元素)
		p = head->next;
		while(p != NULL)
		{
			scanf("%d%f",&p->num,&p->grade); 
			p = p->next;
		}
		printf("\n");
	} 
	
	return head;
}

//按Ascending升序合并 两个链表,返回合并后链表头结点c 
stu mergeLink(stu a,stu b)//传入a,b链表的头结点指针 
{
	int size = sizeof(node);
	//开始合并 
	//构建一个c头结点保存合并结果 
	stu c = NULL;
	c = (stu)malloc(size);
	c->grade = 0;
	c->num = 0;
	//a,b并非一开始就升序 
	//先将a链表变成升序并插入在头指针为c中
	stu t = NULL,q = NULL;
	q = a->next;//指向第一个 放进c链的结点
	a->next = a->next->next;//剔除要放进c链的结点 
	
	c->next = q;//赋值第一个 放入c链
	q->next = NULL;//注意 新加入c链尾的的结点一定得初始化next指针
	t = c;//每次都从c链头找起 
	while(a->next != NULL)
	{
		
		//寻找插入点 
		if(a->next->num > t->next->num)
		{
			t = t->next;
			if(t->next == NULL)//说明下一次循环,会遍历到c链表末尾 
			{
				//即该结点大于c链表所有结点,应该插入 c链表末尾
				//从a链中剔除该结点
				q = a->next;
				a->next = a->next->next;
				//把该结点放在c链的末尾 
				q->next = NULL;//注意 新加入c链尾的的结点一定得初始化next指针
				t->next = q;
				//插入后说明 该结点插入完毕,下一次结点 初始化开头 
				t = c;//每次都从c链头找起 
			}
		}
		else//找到 
		{
			//从a链中剔除该结点 
			q = a->next;
			a->next = a->next->next;
			//把该结点放在c链中合适位置
			q->next = t->next; 
			t->next = q;
			
			//插入后说明 该结点插入完毕,下一次结点 初始化开头 
			t = c;//每次都从c链头找起 
		}
	}
	
	//再 将b链表中 学号升序插入到c中 
	q = NULL;//初始 
	t = c;//每次都从c链头找起 
	while(b->next != NULL)
	{
		
		//寻找插入点 
		if(b->next->num > t->next->num)
		{
			t = t->next;
			if(t->next == NULL)//说明下一次循环,会遍历到c链表末尾 
			{
				//即该结点大于c链表所有结点,应该插入 c链表末尾
				//从b链中剔除该结点
				q = b->next;
				b->next = b->next->next;
				//把该结点放在c链的末尾 
				q->next = t->next; 
				t->next = q;
				
				//插入后说明 该结点插入完毕,下一次结点 初始化开头 
				t = c;//每次都从c链头找起 
			}
		}
		else//找到 
		{
			//从b链中剔除该结点 
			q = b->next;
			b->next = b->next->next;
			//把该结点放在c链中合适位置
			q->next = t->next; 
			t->next = q;
			
			//插入后说明 该结点插入完毕,下一次结点 初始化开头 
			t = c;//每次都从c链头找起 
		}
	}
	return c;
}

//打印链表结点元素 
void prinLink(stu a);
//释放链表(传入头指针) 
void freeLink(stu head);
int main()
{
	stu a,b,c;//a,b两个链表 
	int n,m,i = 0;//a,b两个链表的大小
	
	//控制台录入a链表,初始化 a链表
	scanf("%d",&n);
	a = InitLink(a,n,1);//手动赋值 
	//初始b 
	scanf("%d",&m);
	b = InitLink(b,m,1);//手动赋值 
	
	
	//查看初始化结果
	printf("a:\n");
	prinLink(a);
	printf("b:\n");
	prinLink(b);
	//查看合并结果
	c = mergeLink(a,b);
	printf("c:\n");
	prinLink(c);
	
	//释放a,b,c链表
	freeLink(a);
	freeLink(b); 
	freeLink(c); 
	
	return 0;
}
//释放链表(传入头指针) 
void freeLink(stu head)
{
	stu q = NULL;
	//头插法 释放元素 
	while(head->next != NULL)
	{
		q = head->next;//要释放结点 
		head->next = head->next->next;//剔除该结点 
		free(q);//释放这个被剔除的 结点 
	}
	free(head);//释放头指针 
	q = head = NULL;//初始化 指针 
	return;
}
//打印链表结点元素 
void prinLink(stu a)
{
	stu p = a->next;
	while(p != NULL)
	{
		printf("%d %.2f\n",p->num,p->grade);
		p = p->next;
	}
	printf("----\n");
	return;
}

 

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值