链表翻转
给出一个链表和一个数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);
}