LeetCdoe合并两个有序链表——C

向右看齐 2023-06-14 14:53 105阅读 0赞

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/merge-two-sorted-lists

一、题目描述

将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。

  1. 示例:
  2. 输入:1->2->4, 1->3->4
  3. 输出:1->1->2->3->4->4

二、题解

(1)递归
通过比较链表首位大小,小的链表后移,递归返回小的值

  1. struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2) {
  2. if(l1==NULL)
  3. return l2;
  4. if(l2==NULL)
  5. return l1;
  6. if(l1->val < l2->val){
  7. l1->next = mergeTwoLists(l1->next,l2); //递归
  8. return l1;
  9. }else{
  10. l2->next = mergeTwoLists(l1,l2->next); //递归
  11. return l2;
  12. }
  13. }

(2)类似迭代
通过比较链表首位大小,把小的链表的值拼接到返回链表后,然后后移,一方为空结束,另一条链表直接全部拼接到后面。

  1. struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2) {
  2. struct ListNode* prehead = (struct ListNode*)malloc(sizeof(struct ListNode));
  3. struct ListNode* prev = prehead; //prehead 是头结点,利用 prev 结点拼接(尾插法 )
  4. while (l1 != NULL && l2 != NULL) {
  5. if (l1->val <= l2->val) {
  6. //l1 <= l2,把 l1 接到 prev 后面
  7. prev->next = l1;
  8. l1 = l1->next; //l1 后移一个结点
  9. }
  10. else {
  11. //否则, 把 l2 接到 prev 后面
  12. prev->next = l2;
  13. l2 = l2->next; //l2 后移一个结点
  14. }
  15. prev = prev->next; //prev 后移
  16. }
  17. prev->next = l1 == NULL ? l2 : l1; //其中有一个为空结束,如果 l1==NULL,就把 l2 拼接到 prev 后面,否则就把 l1 拼接到 prev 后面
  18. return prehead->next;
  19. }

三、调试

(1)完整代码

  1. #include<stdio.h>
  2. #include<malloc.h>
  3. struct ListNode {
  4. int val;
  5. struct ListNode* next;
  6. };
  7. //尾插法
  8. void CreateListR(struct ListNode*& L, int array[], int n) {
  9. ListNode* s, * r;
  10. L = (ListNode*)malloc(sizeof(ListNode)); //创建头结点
  11. r = L; //r 始终指向尾结点,初始时指向头结点 (头结点序号为 0)
  12. for (int i = 0; i < n; i++) {
  13. //循环建立数据节点 s
  14. s = (ListNode*)malloc(sizeof(ListNode));
  15. s->val = array[i]; //赋值
  16. r->next = s; //将结点 s 插入到结点 r 之后
  17. r = s;
  18. }
  19. r->next = NULL; //尾结点其 next 域置为 NULL
  20. }
  21. //输出线性表
  22. void Display(struct ListNode* L) {
  23. ListNode* p = L->next; //p 指向首结点 (首结点序号为 1)
  24. while (p != NULL) {
  25. //不为空,依次遍历
  26. printf("%d", p->val);
  27. if (p->next != NULL) {
  28. printf("->");
  29. }
  30. p = p->next; //p 移向下一个节点
  31. }
  32. printf("\n");
  33. }
  34. //迭代
  35. struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2) {
  36. }
  37. //递归
  38. struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2) {
  39. }
  40. int main() {
  41. int array1[] = {
  42. 1,2,4 };
  43. int array2[] = {
  44. 1,3,4 };
  45. int n1 = sizeof(array1) / sizeof(int);
  46. int n2 = sizeof(array2) / sizeof(int);
  47. struct ListNode* l1 = (struct ListNode*)malloc(sizeof(struct ListNode));
  48. struct ListNode* l2 = (struct ListNode*)malloc(sizeof(struct ListNode));
  49. CreateListR(l1, array1, n1);
  50. CreateListR(l2, array2, n2);
  51. printf("创建单链表成功!\n");
  52. printf("输出单链表\n");
  53. Display(l1);
  54. Display(l2);
  55. struct ListNode* l3 = mergeTwoLists(l1, l2);
  56. //如果只是 l3,不知道为什么第一个是 0,所以改为 l3->next
  57. Display(l3->next);
  58. return 0;
  59. }

四、结果

(1)控制台输出
在这里插入图片描述
(2)递归
在这里插入图片描述

(3)迭代
在这里插入图片描述

发表评论

表情:
评论列表 (有 0 条评论,105人围观)

还没有评论,来说两句吧...

相关阅读

    相关 合并有序

    合并两个有序链表 1、题目 题目要求:将两个升序链表合并为一个新的升序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例: 输