#include <iostream>
using namespace std;
struct ListNode
{
int value;
ListNode* next;
ListNode(int value, ListNode* node) :value(value), next(node)
{
}
};
ListNode* reversList(ListNode *head)
{
//如果没有节点或者只有一个节点,直接返回本身,
//只有一个节点时,这个值也可以看作反转链表的反向的头指针
if (head == NULL || head->next == NULL)
{
return head;
}
//递归调用reversList,递的终点是head->next自身就是最后一个节点,
//此时返回值就是这个节点本身,也是反转链表的头节点
ListNode* reversrHead = reversList(head->next);
//递归第一次归来时,执行的是:即head->next表示最后一个节点时,反转操作
head->next->next = head;
head->next = NULL;
//归的操作,从来没有改变过reversrHead的值,归只改了每个节点的指向,
//reversrHead始终是反转链表的头,即和20行的head表示一个地址
return reversrHead;
}
ListNode* reverseKgroup(ListNode* head , int k)
{
//增加一个头节点
ListNode* dump = new ListNode(-1, NULL);
dump->next = head;
//思路分析
//1.找出需要反转的反转区间
//2.隔离这个反转区间
//3.对隔离区间进行反转
//4.循环到第1步,寻找新的反转区间,然后隔离,然后再反转....,所以 1 2 3 是在循环体内
//反转区间的前一个结点,这个节点的next指向反转区间的第一个节点,
//dump是为了充当返回值,不能动,所以有了临时变量pre
ListNode* pre = dump;
while (pre != NULL && pre->next != NULL)
{
//start是反转区间的第一个节点
ListNode* start = pre->next;
//初始化,初始化是pre的时候,正好移动K此能到end应该在的位置,也就是反转区间的最后一个节点
ListNode* end = pre;
//寻找反转区间的end的实际应该在的位置
for (int i = 0; i < k && end != NULL; i++)
{
end = end->next;
}
//如果end为NULL,说明区间元素不够,就不用进行下面的反转逻辑了,直接退出
if (end == NULL)
{
break;
}
//end马上要设置为null,才能把反转区间隔离,然后进行区间的反转,此时要前保存end的next的位置,防止区间反转后连接不进去原来的链表
ListNode * endNextRecord = end->next;
//隔离反转区间,反转链表区域的最后一个节点尾部断开
end->next = NULL;
//隔离反转区间,反转链表区域的第一个节点与头部断开
pre->next = NULL;
//反转隔离区间,反转后的链表的头指针应该被pre指向,头部连接反转后的链表区域的第一个节点
pre->next = reversList(start);
//反转后的链表,start指向的元素是第一个区间反转后的最后一个元素,
//把这个元素指向endNextRecord,反转链表接入原链表
start->next = endNextRecord;
//pre移动到下一个反转区域的最前方
pre = start;
}
return dump->next;
}
void traverseList(ListNode* head)
{
while (head != NULL)
{
std::cout << head->value << " ";
head = head->next;
}
std::cout << std::endl;
}
int main()
{
ListNode* node1 = new ListNode(1, NULL);
ListNode* node2 = new ListNode(2, NULL);
ListNode* node3 = new ListNode(3, NULL);
ListNode* node4 = new ListNode(4, NULL);
ListNode* node5 = new ListNode(5, NULL);
ListNode* node6 = new ListNode(6, NULL);
ListNode* node7 = new ListNode(7, NULL);
node1->next = node2;
node2->next = node3;
node3->next = node4;
node4->next = node5;
node5->next = node6;
node6->next = node7;
traverseList(node1);
int k = 3;
ListNode * newHead = reverseKgroup(node1, k);
traverseList(newHead);
}
K个一组链表反转
于 2022-03-19 23:53:22 首次发布