当前位置:   article > 正文

链表反转(指定区间)_链表内指定区间反转

链表内指定区间反转
  1. #include<iostream>
  2. struct ListNode
  3. {
  4. int value;
  5. ListNode *next;
  6. ListNode(int value, ListNode* node) : value(value), next(node)
  7. {
  8. }
  9. };
  10. ListNode * mearge(ListNode *head1, ListNode *head2)
  11. {
  12. //合并后的新的有序的链表都往这个假的头上面插
  13. ListNode *tempHead = new ListNode(-1, nullptr);
  14. ListNode *willBeInseart = tempHead;//新元素要插在哪个节点的后面,willBeInseart始终是新链表构造过程中的最后一个节点
  15. while (head1 != NULL && head2 != NULL)
  16. {
  17. if (head1->value > head2->value)
  18. {
  19. willBeInseart->next = head2;
  20. head2 = head2->next;
  21. }
  22. else
  23. {
  24. willBeInseart->next = head1;
  25. head1 = head1->next;
  26. }
  27. willBeInseart = willBeInseart->next;
  28. }
  29. if (head1 != NULL)
  30. {
  31. willBeInseart->next = head1;
  32. }
  33. if(head2 != NULL)
  34. {
  35. willBeInseart->next = head2;
  36. }
  37. return tempHead->next;
  38. }
  39. void traverseList(ListNode *head)
  40. {
  41. while (head != NULL)
  42. {
  43. std::cout << head->value << " ";
  44. head = head->next;
  45. }
  46. std::cout << std::endl;
  47. }
  48. ListNode *reverseBetween(ListNode *oldList, int begin, int end)
  49. {
  50. if (oldList == NULL) return NULL;
  51. if (begin == end) return oldList;
  52. if (begin > end)
  53. {
  54. int temp = begin;
  55. begin = end;
  56. end = begin;
  57. }
  58. //当链表begin是1的时候,要借助这个虚拟的头节点
  59. ListNode *tempDumpHead = new ListNode(-1, nullptr);
  60. //虚拟头节点指向了原链表的头
  61. tempDumpHead->next = oldList;
  62. //pre的作用是指向反转区间的begin所在节点的前一个结点,当begin为1时,pre的值就是tempDumpHead,所以用他的值初始化pre,当begin>1时,更新pre的值
  63. ListNode *pre = tempDumpHead;
  64. //cur的作用是指向反转区间内即将要进行反转的第一个节点,当begin为1时,cur的值就是oldList,所以用他的值初始化cur,当begin>1时,更cur的值
  65. ListNode *cur = oldList;
  66. //退出for循环后,pre指向的是要反转区间的前一个节点,cur指向要进行反转处理的节点,即反转区间的第一个节点
  67. for (int i = 0; i < begin - 1; i++)
  68. {
  69. pre = pre->next;
  70. cur = cur->next;
  71. }
  72. //反转思路是把cur指向的节点的下一个节点放到了pre的后面(pre是不动的);
  73. //比如原始链表如下:
  74. //1 > 2 > 3 > 4 > 5 > 6
  75. //如果begin = 2即第二个节点,end = 5即第五个节点
  76. //开始反转循环处理:
  77. //pre是指向第一个节点1的;cur指向第二个节点2
  78. //第一步:把cur指向的节点的下一个节点放到了pre的后面,结果是
  79. //1 3 2 4 5 6
  80. //此时pre仍然是指向第一个节点1的;cur指向第三个节点2
  81. //第二步:把cur指向的节点的下一个节点放到了pre的后面,结果是
  82. //1 4 3 2 5 6
  83. //此时pre仍然是指向第一个节点1的;cur指向第四个节点2
  84. //第三步:把cur指向的节点的下一个节点放到了pre的后面,结果是
  85. //1 5 4 3 2 6
  86. //只需要依次把反转区间内的3 4 5 依次放到pre的后面, 执行了 end - begin 即5 - 2 = 3次循环
  87. //即依次处理反转区间内的需要处理的节点,
  88. //只要处理end - begin个节点据可以了,
  89. //即使区间内有end - begin + 1 个元素,
  90. //但是只要end - begin个元素的位置对了,
  91. //区间内的反转就完成了
  92. for (int i = 0; i < end - begin; i++)
  93. {
  94. //把cur指向的节点的下一个节点放到了pre的后面(pre是不动的)
  95. //设置临时变量,保存当前需萎翻转节点的后面的节点
  96. ListNode *bakNode = cur->next;
  97. // 这个时候,让 temp 和 cur 两个节点翻转一下
  98. // 比如,一开始 i = 0 的时候 cur 为 2, temp 为 3
  99. // 执行完下面的代码,如果原链表是
  100. // 1 --> 2 --> 3 --> 4 --> 5
  101. // 变成了
  102. // 1 --> 3 --> 2 --> 4 --> 5
  103. // cur 的下一节点是等号右侧的值
  104. // i = 0 的时候, cur 为 2,cur.next.next 的值是 4
  105. // 所以,这行代码让 cur 的下一节点不是 3 ,而是 4
  106. // 2 --> 4
  107. // 等价于 cur.next = temp.next
  108. cur->next = cur->next->next;
  109. // temp 的下一节点是等号右侧的值
  110. // i = 0 的时候, temp 为 3,pre 为 1,pre 下一节点的值是 2
  111. // 所以,这行代码让 temp 的下一节点不是 4 ,而是 2
  112. // 3 --> 2
  113. bakNode->next = pre->next;
  114. // pre 的下一节点是等号右侧的值
  115. // i = 0 的时候, pre 为 1,temp 的值是 3
  116. // 所以,这行代码让 pre 的下一节点为 3
  117. // 1 --> 3
  118. pre->next = bakNode;
  119. // i = 0 结束之后,链表变成了
  120. // 1 --> 3 --> 2 --> 4 --> 5
  121. }
  122. return tempDumpHead->next;
  123. }
  124. int main()
  125. {
  126. ListNode * node1 = new ListNode(1, nullptr);
  127. ListNode * node2 = new ListNode(2, nullptr);
  128. ListNode * node3 = new ListNode(3, nullptr);
  129. ListNode * node4 = new ListNode(4, nullptr);
  130. ListNode * node5 = new ListNode(5, nullptr);
  131. ListNode * node6 = new ListNode(6, nullptr);
  132. node1->next = node2;
  133. node2->next = node3;
  134. node3->next = node4;
  135. node4->next = node5;
  136. node5->next = node6;
  137. ListNode *head = node1;
  138. std::cout << "oldList" << std::endl;
  139. traverseList(head);
  140. ListNode *newHead = reverseBetween(head,2,5);//反转链表第2个节点到第5个节点区间的链
  141. std::cout << "newList" << std::endl;
  142. traverseList(newHead);
  143. }

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

闽ICP备14008679号