C语言——将两个递增的有序链表合并为一个递增的有序链表

考察了指针 和链表的相关知识,用尾插法可以直接进行合并

将 有序的链表p1 和 p2 的头部比较值的大小,然后将比较后得出的头结点 插入到新链表的尾部,不断循环遍历,最后输出一个新链表

原理:需要新建两个链表p1和p2, 直接对原有的p1和p2两个链表进行操作,

用p1和p2的头部对 新链表  使用尾插法,

比较p1和p2的头部值,将 较大的头部插入 新链表 的尾部,同时对移走头部的链表进行头部删除

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

typedef struct NUM {//定义一个结构体

	int num;
	struct  NUM* pNext;
} num, * pnum;

//该子函数原理:
//           建立了一个新链表,用尾插法 将p1和p2两个链表插入到新链表的尾部,同时对移动的旧链表的结点删除
void insert(pnum *pphead,pnum *pptail,int Input) {

	pnum pnew = (pnum)calloc(sizeof(num), 1);

	memset(pnew, 0, sizeof(num));

	pnew->num = Input;//指向 新输入的值

	pnum pre = *pphead, pcur = *pphead;

	if (NULL==*pphead) {   //判断链表是否为空

		//如果链表为空
		*pphead = pnew;
		*pptail = pnew;
	}
	else if(Input <=(*pphead)->num) {

		(*pptail)->pNext = pnew;
		*pptail = pnew;
	}
	else {

		while (pcur !=NULL) {

			if (pcur->num >Input) {

				pnew->pNext = pcur;
				pre->pNext = pnew;
				break;
			}
			pre =pcur;
			pcur = pcur->pNext;
		}
		if (NULL==pcur) {

			pre->pNext = pnew;
			*pptail = pnew;
		}
	}
}

//该子函数 是将链表合并
void merge(pnum *phead,pnum *ptail,pnum *phead1,pnum *phead2) {

	pnum p1 = *phead1;
	pnum p2 = *phead2;

	while (p1 !=NULL &&p2 !=NULL) {

		if (*phead==NULL) {

			if (p1->num >p2->num) {

				*phead = p2;
				p2 = p2->pNext;
				(*phead)->pNext = NULL;
				*ptail = *phead;
			}
			else {

				*phead = p1;
				p1 = p1->pNext;
				(*phead)->pNext = NULL;
				*ptail = *phead;
			}
		
		}
		else {
			if (p1->num > p2->num) {

				(*ptail)->pNext = p2;
				*ptail = p2;
				p2 = p2->pNext;
			}
			else {

				(*ptail)->pNext = p1;
				*ptail = p1;
				p1 = p1->pNext;
			}

		}
	}
	if (p1) {

		(*ptail)->pNext = p1;
		while (p1->pNext) {

			p1 = p1->pNext;
		}
		*ptail = p2;
	}
	if (p2) {

		(*ptail)->pNext = p2;
		while (p2->pNext) {

			p2= p2->pNext;
		}
		*ptail = p1;
	}
}


//该子函数 是为了打印链表 显示出最后结果
void print(pnum *phead) {

	pnum pcur = *phead;
	while (pcur) {

		printf("%3d",pcur->num);
		pcur = pcur->pNext;
	}
	printf("\n");
}

int main() {

	pnum phead1 = NULL;//定义头指针  链表1
	pnum ptail1 = NULL;//定义尾指针

	pnum phead2 = NULL;//定义头指针  链表2
	pnum ptail2 = NULL;//定义尾指针

	pnum phead = NULL;//定义头指针   新链表用来放 其他两个链表
	pnum ptail = NULL;//定义尾指针

	int InPut;//定义要输入的数

	
	while (scanf_s("%d", &InPut) != EOF) {

		insert(&phead1,&ptail1,InPut);//调用子函数 在子函数中具体实现功能
	}

	printf("链表 1 如下:\n");
	print(&phead1);

	printf("=========================================\n");

	while (scanf_s("%d", &InPut) != EOF) {

		insert(&phead2, &ptail2, InPut);//调用子函数 在子函数中具体实现功能
	}

	printf("链表 2 如下:\n");
	print(&phead2);
	printf("=========================================\n");

	merge(&phead,&ptail,&phead1,&phead2);
	printf("合并后的新链表 如下:\n");
	print(&phead);
	
	return 0;
	
}
	

运行结果:

### 回答1: 可以使用合并两个排序链表的方法来将两个递增的单链表合并一个递增的单链表。首先分别定义两个指针来指向两个链表的头结点,然后比较指针指向的节点值,将值较小的节点添加到新链表中,并将指针指向下一个节点,直到两个指针均到达链表尾部。 ### 回答2: 算法步骤如下: 1. 首先,创建一个新的单链表,用来存放合并后的链表。 2. 定义两个指针p和q分别指向两个递增链表的头节点。 3. 比较p和q指针所指节点的值,将较小值的节点添加到新的单链表中,并将指针向后移动一位。 4. 当其中一个链表遍历结束时,将另一个链表剩余的节点添加到新的单链表中。 5. 返回新的单链表即为合并后的递增链表。 具体实现如下所示: ```python # 定义节点类 class ListNode: def __init__(self, val=0, next=None): self.val = val self.next = next def mergeTwoLists(l1, l2): # 创建一个dummy节点作为新链表的头节点 dummy = ListNode(0) p = l1 q = l2 current = dummy # 循环比较两个链表的节点值,并将较小值的节点添加到新链表中 while p and q: if p.val < q.val: current.next = p p = p.next else: current.next = q q = q.next current = current.next # 将剩余的节点添加到新链表中 if p: current.next = p if q: current.next = q # 返回新链表中去掉dummy节点后的头节点 return dummy.next ``` 时间复杂度:合并两个链表需要遍历所有节点,时间复杂度为O(m + n),其中m和n分别为两个链表的长度。 空间复杂度:只使用了常数级别的额外空间,空间复杂度为O(1)。 ### 回答3: 将两个递增的单链表合并一个递增的单链表的方法是,首先定义一个新的单链表,然后分别定义两个指针,分别指向两个原始链表的头结点。通过比较两个指针所指节点的值,将值较小的节点加入到新的链表中,并将指针指向下一个节点。重复这个过程,直到其中一个链表为空。然后将另一个非空链表剩余的节点直接添加到新的链表的末尾。 具体实现如下: 1. 创建一个链表,定义一个头指针和一个当前指针,将头指针指向新链表的头节点。 2. 分别定义两个指针p和q,p指向第一个链表的头结点,q指向第二个链表的头结点。 3. 循环比较p和q指向的节点的值,将值较小的节点接入新链表,并将指针后移。 4. 当p或q其中一个指针为空时,停止循环。 5. 若p非空,则将p后面的节点全部接入新链表。 6. 若q非空,则将q后面的节点全部接入新链表。 7. 返回新链表的头节点。 代码示例: ```python class ListNode: def __init__(self, val=0, next=None): self.val = val self.next = next def merge_two_lists(l1: ListNode, l2: ListNode) -> ListNode: dummy = ListNode(0) # 创建一个哑结点作为新链表的头节点 cur = dummy # 当前结点指针 while l1 and l2: if l1.val <= l2.val: cur.next = l1 l1 = l1.next else: cur.next = l2 l2 = l2.next cur = cur.next if l1: cur.next = l1 if l2: cur.next = l2 return dummy.next ``` 以上代码通过比较两个链表的节点值大小,不断将较小的值的节点添加到新链表中,直到其中一个链表为空。然后直接将另一个链表剩余的部分添加到新链表的末尾。最后返回新链表的头节点,即为合并后的递增链表
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值