以下是用C语言编写的合并两个非递减链表的算法,并在每行代码后面添加了注释。
#include <stdio.h>
#include <stdlib.h>
// 定义链表节点结构体
struct ListNode {
int val; // 链表节点存储的值
struct ListNode *next; // 指向下一个链表节点的指针
};
// 合并两个非递减链表
struct ListNode* mergeTwoLists(struct ListNode* A, struct ListNode* B) {
// 如果A为空,则直接返回B
if (A == NULL) {
return B;
}
// 如果B为空,则直接返回A
if (B == NULL) {
return A;
}
// 定义一个指向合并后链表头结点的指针
struct ListNode* head = NULL;
// 定义一个指向当前合并后链表尾部的指针
struct ListNode* tail = NULL;
// 选择头结点,头结点为两个链表头结点中较小的一个
if (A->val <= B->val) {
head = A;
A = A->next;
} else {
head = B;
B = B->next;
}
// 当前合并后链表的尾部为头结点
tail = head;
// 遍历A和B链表,将较小的节点加入到合并后的链表中
while (A != NULL && B != NULL) {
if (A->val <= B->val) {
tail->next = A;
A = A->next;
} else {
tail->next = B;
B = B->next;
}
// 每加入一个节点,当前合并后链表的尾部就更新为新加入的节点
tail = tail->next;
}
// 将A或B剩余的节点加入到合并后的链表中
if (A != NULL) {
tail->next = A;
} else {
tail->next = B;
}
// 返回合并后的链表头结点
return head;
}
mergeTwoLists 是一个函数名,它的意思是“合并两个链表”。在这个函数中,我们将两个非递减链表 A 和 B 合并成一个非递减链表 C,并将 C 的头结点作为函数返回值返回。
这个函数的功能非常常见,因为在实际开发中,很多时候我们需要将两个链表合并成一个链表,以便进行后续的操作,例如链表的排序、查找、删除等等。
给出一个可以运行的C程序
#include <stdio.h>
#include <stdlib.h>
// 定义链表节点结构体
struct ListNode {
int val; // 链表节点存储的值
struct ListNode *next; // 指向下一个链表节点的指针
};
// 合并两个非递减链表
struct ListNode* mergeTwoLists(struct ListNode* A, struct ListNode* B) {
// 如果A为空,则直接返回B
if (A == NULL) {
return B;
}
// 如果B为空,则直接返回A
if (B == NULL) {
return A;
}
// 定义一个指向合并后链表头结点的指针
struct ListNode* head = NULL;
// 定义一个指向当前合并后链表尾部的指针
struct ListNode* tail = NULL;
// 选择头结点,头结点为两个链表头结点中较小的一个
if (A->val <= B->val) {
head = A;
A = A->next;
} else {
head = B;
B = B->next;
}
// 当前合并后链表的尾部为头结点
tail = head;
// 遍历A和B链表,将较小的节点加入到合并后的链表中
while (A != NULL && B != NULL) {
if (A->val <= B->val) {
tail->next = A;
A = A->next;
} else {
tail->next = B;
B = B->next;
}
// 每加入一个节点,当前合并后链表的尾部就更新为新加入的节点
tail = tail->next;
}
// 将A或B剩余的节点加入到合并后的链表中
if (A != NULL) {
tail->next = A;
} else {
tail->next = B;
}
// 返回合并后的链表头结点
return head;
}
// 测试程序
int main() {
// 创建链表A
struct ListNode* A = (struct ListNode*)malloc(sizeof(struct ListNode));
A->val = 1;
A->next = (struct ListNode*)malloc(sizeof(struct ListNode));
A->next->val = 2;
A->next->next = (struct ListNode*)malloc(sizeof(struct ListNode));
A->next->next->val = 4;
A->next->next->next = NULL;
// 创建链表B
struct ListNode* B = (struct ListNode*)malloc(sizeof(struct ListNode));
B->val = 1;
B->next = (struct ListNode*)malloc(sizeof(struct ListNode));
B->next->val = 3;
B->next->next = (struct ListNode*)malloc(sizeof(struct ListNode));
B->next->next->val = 4;
B->next->next->next = NULL;
// 合并链表A和B
struct ListNode* C = mergeTwoLists(A, B);
// 遍历合并
while (C != NULL) {
printf("%d ", C->val);
C = C->next;
}
printf("\n");
return 0;
}
上述程序中,我们定义了一个链表节点的结构体,以及合并两个非递减链表的函数 mergeTwoLists
,这个函数的实现方式是遍历两个链表,将较小的节点逐一加入到合并后的链表中,最终返回合并后的链表头结点。
程序中还包含一个 main
函数,用于测试 mergeTwoLists
函数的正确性。我们先创建两个非递减链表 A 和 B,分别存储 1 -> 2 -> 4 和 1 -> 3 -> 4。然后调用 mergeTwoLists
函数将两个链表合并,得到新的非递减链表 C,最后遍历链表 C 并输出每个节点的值。