链表归并与并集相关算法题|两递增归并为递减到原位|b表归并到a表|两递减归并到新链表(C)

两递增归并为递减到原位

假设有两个按元素递增次序排列的线性表,均以单链表形式存储。将这两个单链表归并为一个按元素递减次序排列的单链表,并要求利用原来两个单链表的节点存放归并后的单链表

算法思想

因为两链表已按元素值递增次序排列,将其合并时,均从第一个节点起进行比较,将小的链入链表中,同时后移链表工作指针
要求结果链表按元素值递减次序排列,在归并的同时,将链表节点逆置
![[Pasted image 20241110144022.png]]

将la断开,置为NULL
![[Pasted image 20241110144109.png]]

cura和curb开始遍历,取小的头插,相当于逆置
cura<curb,
用next保存cura的下一个节点
![[Pasted image 20241110144251.png]]

将cura的next指向la的next,即NULL
![[Pasted image 20241110144344.png]]

la的next指向cura
![[Pasted image 20241110144407.png]]

cura指向next
![[Pasted image 20241110144430.png]]

完成头插

LinkList Union(LinkList la, lb)
{
	// cura和curb分别是链表A和B的工作指针,next保存下一个节点
	LNode* cura = la->next, *curb = lb->next, *next;
	la->next = NULL;      // la作结果链表的头指针,先将结果链表置为NULL

	while (cura && curb)
	{
		if (cura->data <= curb->data)
		{
			// 将cura的后继节点存于next
			next = cura->next;
			// 将cura节点链于结果表中,同时逆置
			cura->next = la->next;
			la->next = cura;
			// 恢复cura为当前待比较节点
			cura = next;
		}
		else
		{
			next = curb->next;
			curb->next = la->next;
			la->next = curb;
			curb = next;
		}
	}
	// 将la表剩余的部分链入结果表,并逆置
	// 两个while只能运行一个
	while (cura)
	{
		next = cura->next;
		cura->next = la->next;
		la->next = cura;
		cura = next;
	}
	while (curb)
	{
		next = curb->next;
		curb->next = la->next;
		la->next = curb;
		curb = next;
	}
	return la;
}

b表归并到a表

设有两个无头节点的单链表,头指针分别为ha,hb,两链表的数据都按递增次序存放,现要求将hb表归并到ha表中,且归并后ha仍为递增,归并中ha表中已有的数据若hb中也有,则hb中的数据不归并到ha中,hb的链表在算法中不允许破坏

算法思想

由于无头节点,为方便建立头节点,最后删掉
数据相同的节点,不合并到结果链表中
hb表不能被破坏,即要归并的时候,要创建新节点

申请头节点la指向ha的头节点,cura和curb分别指向ha和hb的第一个节点,prev指针指向cura的前一个节点
![[Pasted image 20241110230637.png]]

cura和curb向后遍历,如果cura小于curb
prev的next指向cura,prev指向cura,cura指向它的下一个
![[Pasted image 20241110230831.png]]

如果cura大于curb
malloc一个new节点,使得new的data等于curb的data
![[Pasted image 20241110231033.png]]

prev的next指向new,prev指向new,curb指向它的下一个节点
![[Pasted image 20241110231213.png]]

如果cura等于curb
cura链入结果链表,curb继续往后遍历

LinkList Union(LinkList ha, hb)
{
	// 申请头节点,以便操作
	LinkList la;
	la = (LinkList)malloc(sizeof(LNode));
	la->next = ha;
	// cura时ha链表的工作指针
	LNode* cura = ha;
	// curb时hb的工作指针
	LNode* curb = hb;
	// prev指向当前待合并节点的前驱
	LNode* prev = la;

	while(cura && curb)
	{
		// 处理ha中的数据
		if (cura->data < curb->data)
		{
			prev->next = cura;
			prev = cura;
			cura = cura->next;
		}
		// 处理hb中的数据
		else if (cura->data > curb->data)
		{
			// 申请空间
			LNode* new = (LNode*)malloc(sizeof(LNode));
			// 将新节点链入结果链表			
			new->data = curb->data;
			prev->next = new;
			prev = new;
			// 链表中工作节点后移
			curb = curb->next;
		}
		// 处理cura->data == curb->data
		else
		{
			// 只要ha的数据
			prev->next = cura;
			prev = cura;
			cura = cura->next;
			// 不要hb的数据
			curb = curb->next;
		}
	}
	// 将两链表中剩余部分链入结果链表
	if (cura)
		prev->next = cura;
	if (curb)
		prev->next = curb;
	// 释放头节点
	free(la);
	return ha;
}

两递减归并到新链表

已知头指针分别为la和lb的带头节点的单链表中,节点按元素值非递减有序排列。
将la和lb两链表归并成一个节点按元素值非递减有序排列的单链表,头指针为lc

LinkList Union(LinkList &la, &lb)
{
	LNode* cura = la->next, curb = lb->next;
	LinkList lc = (LinkList)malloc(sizeof(LNode));
	LNode* curc = lc;

	while (cura && curb)
	{
		if (cura->data < curb->data)
		{
			curc->next = cura;
			curc = cura;
			cura = cura->next;
		}
		else
		{
			curc->next = curb;
			curc = curb;
			curb = curb->next;
		}
	}
	if (cura)
		curc->next = cura;
	if (curb)
			curc->next = curb;
	free(la);
	free(lb);
	return lc;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值