当前位置:   article > 正文

Ieetcode——21.合并两个有序链表

Ieetcode——21.合并两个有序链表

21. 合并两个有序链表 - 力扣(LeetCode)

合并两个有序链表我们的思路是创建一个新链表,然后遍历已知的两个有序链表,并比较其节点的val值,将小的尾插到新链表中,然后继续遍历,直到将该两个链表的全部节点全部尾插到新链表中。下面我来画图分析一下如何进行遍历和尾插:

遍历和尾插的过程就如上图一般,接下来我们来实现代码。

我们在写代码的时候还应该注意一些特殊情况:有序链表为空的情况。 

我们看,对于这两种情况下:如果两个有序链表都为空,那么就返回NULL;如果只有一个为空,那就返回另外一个。 

分析到这里,我们就可以开始写代码了。(注意:该代码只包含解决该问题的函数部分,不包含主函数内容)

  1. typedef struct ListNode ListNode;
  2. struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2)
  3. {
  4. //有空链表
  5. if(list1 == NULL)
  6. {
  7. return list2;
  8. }
  9. if(list2 == NULL)
  10. {
  11. return list1;
  12. }
  13. //无空链表
  14. //创建新链表,遍历两链表
  15. ListNode* newlist = NULL;
  16. ListNode* newtail = NULL;
  17. while(list1 && list2)//这两个链表只要有一个走到了NULL,就说明为NULL的链表已经全部尾插完了
  18. {
  19. if(list1->val <= list2->val)
  20. {
  21. if(newlist == NULL)
  22. {
  23. //新链表为空
  24. newlist = list1;
  25. newtail = list2;
  26. }
  27. else
  28. {
  29. //新链表不为空
  30. newtail->next = list1;
  31. newtail = newtail->next;
  32. }
  33. //尾插完后,遍历下一个节点
  34. list1 = list1->next;
  35. }
  36. else
  37. {
  38. if(newlist == NULL)
  39. {
  40. //新链表为空
  41. newlist = list1;
  42. newtail = list2;
  43. }
  44. else
  45. {
  46. //新链表不为空
  47. newtail->next = list1;
  48. newtail = newtail->next;
  49. }
  50. //尾插完后遍历下一个节点
  51. list2 = list2->next;
  52. }
  53. }
  54. //跳出循环,说明有一个链表已经遍历完了,只需将另一个链表的剩余元素尾插到新链表
  55. if(list1 == NULL)
  56. {
  57. //list1遍历完了,将list2尾插到新链表中
  58. newtail->next = list2;
  59. }
  60. else
  61. {
  62. //list2遍历完了,将list1尾插到新链表中
  63. newtail->next = list1;
  64. }
  65. return newlist;
  66. }

我们写完之后,代码虽然可以成功解决问题,但是其中出现了很多重复的代码。 

哨兵位是一个有空间但是没有值的节点,而且是动态开辟的内存空间,所以我们现在就不能直接返回newist了,而是返回newlist->next,但是动态开辟的内存空间我们使用完之后就应该释放掉,所以我们应该先创建一个临时变量将newist->next存起来,然后将newlist释放掉,后返回临时变量。

所以我们要对该代码进行两部分的调整:

部分一:用来解决重复代码

部分二:用来解决动态内存开辟的释放以及哨兵位的引入对返回值的影响 

下面附上完整代码:

  1. typedef struct ListNode ListNode;//避免因为类型名长而对其进行重命名
  2. struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2)
  3. {
  4. //有空链表
  5. if(list1 == NULL)
  6. {
  7. return list2;
  8. }
  9. if(list2 == NULL)
  10. {
  11. return list1;
  12. }
  13. //无空链表
  14. //创建新链表,遍历两链表
  15. ListNode* newlist = (ListNode*)malloc(sizeof(ListNode));
  16. ListNode* newtail = newlist;
  17. while(list1 && list2)//这两个链表只要有一个走到了NULL,就说明为NULL的链表已经全部尾插完了
  18. {
  19. if(list1->val <= list2->val)
  20. {
  21. newtail->next = list1;
  22. newtail = newtail->next;
  23. //尾插完后,遍历下一个节点
  24. list1 = list1->next;
  25. }
  26. else
  27. {
  28. newtail ->next = list2;
  29. newtail = newtail->next;
  30. //尾插完后遍历下一个节点
  31. list2 = list2->next;
  32. }
  33. }
  34. //跳出循环,说明有一个链表已经遍历完了,只需将另一个链表的剩余元素尾插到新链表
  35. if(list1 == NULL)
  36. {
  37. //list1遍历完了,将list2尾插到新链表中
  38. newtail->next = list2;
  39. }
  40. else
  41. {
  42. //list2遍历完了,将list1尾插到新链表中
  43. newtail->next = list1;
  44. }
  45. ListNode* ret = newlist->next;
  46. free(newlist);
  47. newlist = NULL;
  48. return ret;
  49. }

 完!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/533002
推荐阅读
相关标签
  

闽ICP备14008679号