合并两个有序单向链表
简介
本文档介绍了一种使用C语言将两个有序单向链表合并成一个有序单向链表的方法。本文档包含算法的解释、完整的代码实现以及示例用法。
算法解释
将两个有序单向链表合并成一个有序单向链表的基本思路如下:
- 初始化:创建一个哑节点(dummy node)作为新链表的起始点,以简化操作。
- 合并过程:比较两个链表的头节点,选择较小的节点作为新链表的下一个节点,移动相应链表的指针,重复此过程直到其中一个链表为空。
- 处理剩余节点:将非空链表的剩余节点直接连接到新链表的末尾。
- 返回结果:返回哑节点的下一个节点作为合并后的链表的头节点。
在最优情况下,合并两个长度均为N的有序链表的最少比较次数为(2N - 1)。
完整代码
下面是完整的C语言代码实现:
#include <stdio.h>
#include <stdlib.h>
// 定义链表节点结构
struct ListNode {
int val;
struct ListNode* next;
};
// 创建新节点
struct ListNode* createNode(int val) {
struct ListNode* newNode = (struct ListNode*)malloc(sizeof(struct ListNode));
newNode->val = val;
newNode->next = NULL;
return newNode;
}
// 合并两个有序链表
struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2) {
// 创建一个哑节点作为新链表的起始点
struct ListNode dummy;
struct ListNode* tail = &dummy;
dummy.next = NULL;
// 合并两个链表
while (l1 != NULL && l2 != NULL) {
if (l1->val < l2->val) {
tail->next = l1;
l1 = l1->next;
} else {
tail->next = l2;
l2 = l2->next;
}
tail = tail->next;
}
// 将剩余的节点连接到新链表末尾
if (l1 != NULL) {
tail->next = l1;
} else {
tail->next = l2;
}
return dummy.next;
}
// 打印链表
void printList(struct ListNode* head) {
while (head != NULL) {
printf("%d -> ", head->val);
head = head->next;
}
printf("NULL\n");
}
// 释放链表内存
void freeList(struct ListNode* head) {
struct ListNode* temp;
while (head != NULL) {
temp = head;
head = head->next;
free(temp);
}
}
int main() {
// 创建第一个有序链表: 1 -> 3 -> 5
struct ListNode* l1 = createNode(1);
l1->next = createNode(3);
l1->next->next = createNode(5);
// 创建第二个有序链表: 2 -> 4 -> 6
struct ListNode* l2 = createNode(2);
l2->next = createNode(4);
l2->next->next = createNode(6);
// 合并链表
struct ListNode* mergedList = mergeTwoLists(l1, l2);
// 打印合并后的链表
printf("Merged List: ");
printList(mergedList);
// 释放链表内存
freeList(mergedList);
return 0;
}
使用示例
输入
假设我们有两个有序链表:
- 第一个链表:1 -> 3 -> 5
- 第二个链表:2 -> 4 -> 6
运行结果
合并后的链表为:
1 -> 2 -> 3 -> 4 -> 5 -> 6 -> NULL
代码说明
-
结构定义:
struct ListNode
定义了链表节点的结构,包含一个整数值和指向下一个节点的指针。
-
节点创建:
createNode
函数用于创建新节点。
-
合并函数:
mergeTwoLists
函数接收两个有序链表的头节点,返回合并后的有序链表的头节点。