K个一组链表反转

#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);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值