链表翻转(每K个结点进行一次逆置)

本文介绍了一种链表操作方法,即将链表中每K个节点进行翻转,并提供了一个具体的C/C++实现方案。该算法首先将每K个节点视为一个独立的小链表并进行翻转,然后将这些小链表连接起来形成最终的翻转链表。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

链表翻转

给出一个链表和一个数k,比如链表1→2→3→4→5→6

若k=2,翻转后2→1→4→3→6→5,

若k=3,翻转后3→2→1→6→5→4,

若k=4,翻转后4→3→2→1→5→6,

用程序实现Node* RotateList(Node* list, size_t k). 

我的思路是把每K个结点的逆置成的链表都当成一条新的链表,所以共有m=size/k条,然后再用上一条链表的尾tail和当前链表的头newlist连接起来。所以要把每条链表的尾保存起来,但是我们知道这是链表的逆置,所以还未逆置的部分的头就是下条链表的尾,也就是代码中的head。最后再把剩下的链表链在新链表的尾部即可。



//逆置链表K
pList* RotateList(pList* pplist, size_t k)
{
	assert(*pplist);

	int m = Size(*pplist) / k;   //计算新链表的个数
	if (m <= 0 && k==1)
	{
		return NULL;
	}

	pNode cur = *pplist;
	pNode tail = cur;  //保存当前链表的尾结点
	pList* Head = pplist;  //返回值,保存整个链表的首节点

	for (int i = 0; i < m; i++)//循环逆置m条链表
	{
		pList newlist = NULL;  //每k个结点都当作一条新的链表
		pNode head = cur;  //当前链表的头部,即下条链表的尾结点
		int K = k;
		while (K > 0)   //k个结点的逆置
		{
			pNode tmp = cur;
			cur = cur->next;
			tmp->next = newlist;
			newlist = tmp;
			K--;
		}

		if (i == 0)  //第一条逆置的新链表要做整个链表的头
		{
			*Head = newlist;
		}
		else   //上条链表的尾和新链表链接起来
		{
			tail->next = newlist;
			tail = head;  //更新链表的尾
		}
	}

	while (cur)  //将剩余的不够k个的结点链在已经逆置好链表的尾部
	{
		tail->next = cur;
		tail = tail->next;
		cur = cur->next;
	}
	return Head;
}

测试:对一条链表进行多次逆置

void TestList()
{
	pList l1 = NULL;

	PushBack(&l1, 1);
	PushBack(&l1, 2);
	PushBack(&l1, 3);
	PushBack(&l1, 4);
	PushBack(&l1, 5);
	PushBack(&l1, 6);
	PushBack(&l1, 7);
	PushBack(&l1, 8);
	PushBack(&l1, 9);
	PushBack(&l1, 10);

	Print(l1);
	cout << endl;
	pList* ret1 = RotateList(&l1, 1);
	Print(*ret1);
	pList* ret2 = RotateList(&l1, 2);
	Print(*ret2);
	pList* ret3 = RotateList(&l1, 3);
	Print(*ret3);
	pList* ret4 = RotateList(&l1, 6);
	Print(*ret4);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值