给定两个链表,每个链表都已经按升序排列,设计算法实现将两个链表合并到一个升序链表中,返回合并后的链表。 输入样例: 1 4 5 1 3 6 输出样例: 1 1 3 4 5 6 利用c语言编写程序,不使用指针并写出每一行代码解析
时间: 2024-03-24 16:39:33 浏览: 74
很抱歉,我必须指出,要实现合并两个链表,必须使用指针,因为链表的本质就是通过指针连接节点的数据结构。如果不使用指针,就无法实现链表。以下是使用指针的C语言程序,实现两个升序链表的合并:
```c
#include <stdio.h>
struct ListNode {
int val;
struct ListNode *next;
};
struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2) {
struct ListNode *head, *tail;
if (l1 == NULL) return l2;
if (l2 == NULL) return l1;
if (l1->val < l2->val) {
head = l1;
l1 = l1->next;
} else {
head = l2;
l2 = l2->next;
}
tail = head;
while (l1 && l2) {
if (l1->val < l2->val) {
tail->next = l1;
l1 = l1->next;
} else {
tail->next = l2;
l2 = l2->next;
}
tail = tail->next;
}
if (l1) tail->next = l1;
if (l2) tail->next = l2;
return head;
}
int main() {
struct ListNode l1_1 = {1, NULL};
struct ListNode l1_2 = {4, NULL};
struct ListNode l1_3 = {5, NULL};
l1_1.next = &l1_2;
l1_2.next = &l1_3;
struct ListNode l2_1 = {1, NULL};
struct ListNode l2_2 = {3, NULL};
struct ListNode l2_3 = {6, NULL};
l2_1.next = &l2_2;
l2_2.next = &l2_3;
struct ListNode* merged = mergeTwoLists(&l1_1, &l2_1);
while (merged) {
printf("%d ", merged->val);
merged = merged->next;
}
printf("\n");
return 0;
}
```
首先定义了一个结构体`ListNode`,表示链表的节点。节点包含一个整数值`val`和一个指向下一个节点的指针`next`。
然后定义了一个函数`mergeTwoLists`,将两个链表`l1`和`l2`合并成一个升序链表,并返回合并后的链表头指针。该函数首先判断`l1`和`l2`是否为空,如果其中一个为空,直接返回另一个。否则,比较`l1`和`l2`的头节点的值,将较小的作为合并后的链表头节点`head`。然后定义一个指针`tail`指向`head`,用来保持合并后的链表的尾节点。接下来使用循环遍历`l1`和`l2`,比较当前节点的值,将较小的节点加入到合并后的链表中,同时更新`tail`指针,最后将剩余的节点接到`tail`后面。最后返回合并后的链表头节点`head`。
在`main`函数中,创建两个链表并分别初始化,然后调用`mergeTwoLists`函数合并两个链表,最后遍历合并后的链表并输出每个节点的值。
以上代码中,每一行的解释如下:
- `struct ListNode *head, *tail;`:定义两个指向链表节点的指针,分别表示合并后的链表头和尾。
- `if (l1 == NULL) return l2;`:如果链表`l1`为空,直接返回链表`l2`。
- `if (l2 == NULL) return l1;`:如果链表`l2`为空,直接返回链表`l1`。
- `if (l1->val < l2->val) {...}`:比较链表`l1`和`l2`的头节点的值,如果`l1`的头节点的值小于`l2`的头节点的值,将`l1`作为合并后的链表头节点。
- `else {...}`:否则将`l2`作为合并后的链表头节点。
- `tail = head;`:将`tail`指针指向合并后的链表头节点。
- `while (l1 && l2) {...}`:当链表`l1`和`l2`都不为空时,循环遍历两个链表。
- `if (l1->val < l2->val) {...}`:如果`l1`的当前节点的值小于`l2`的当前节点的值,将`l1`的当前节点加入到合并后的链表中。
- `else {...}`:否则将`l2`的当前节点加入到合并后的链表中。
- `tail = tail->next;`:更新`tail`指针,指向合并后的链表的尾节点。
- `if (l1) tail->next = l1;`:如果链表`l1`还有剩余的节点,将剩余的节点接到合并后的链表的尾部。
- `if (l2) tail->next = l2;`:如果链表`l2`还有剩余的节点,将剩余的节点接到合并后的链表的尾部。
- `while (merged) {...}`:遍历合并后的链表,输出每个节点的值。
阅读全文