具体题目详解:
给出一个链表和一个数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,
解决思路:
先分析题目,当节点数有K个时,逆置长度为K的链表,当节点数不足K时,则不做任何处理。
总的思路为:将长度为K的子链表从原链表中拿出,然后逆置,最后将逆置后的子链表再连接回原链表中。
我的解决方法是:编写辅助的两个函数,一个是链表逆置的。另一个是获得链表最后一个的。
具体代码如下:
//断开K长的链表,逆置后,再插回原链表中
Node* RotateList(Node* pHead, size_t k)
{
Node* pNewHead=NULL;
int pos=0;
Node* pLastNode=NULL;
Node* pNextNode=NULL;
Node* pCur=pHead;
pHead=NULL;
while(pCur)
{
pos=0;
pNewHead=pCur;//指向每次需要逆置的头结点
while(pCur && pos<k-1)
{
pCur=pCur->next;
pos++;
}
//如果pCur为空退出循环,说明不够K个节点,所以不用逆置
if(pCur)
{
//保存取出链表的下一个节点,然后断开该段链表
pNextNode=pCur->next;//保证逆置后连到原链表中
pCur->next=NULL;
if(NULL!=pLastNode)
pLastNode->next=NULL;
//逆置该段链表
pNewHead=reverse_list(pNewHead);
//放回原链表中
if(NULL==pHead)//第一次逆置走这
pHead=pNewHead;
else//后来走这
pLastNode->next=pNewHead;
//获得该段链表的最后一个节点
pCur=get_last_node(pNewHead);
pCur->next=pNextNode;
pLastNode=pCur;//保存最后一个节点
pCur=pNextNode;//继续下一段链表
}
else
break;
}
return pHead;
}
//采用头插法逆置链表
Node* reverse_list(Node* pHead)
{
Node* pNewHead=NULL;
Node* pCur=pHead;
Node* pNext=NULL;
if(NULL==pHead)
return NULL;
pNext=pCur->next;
while(pNext)
{
pCur->next=pNewHead;
pNewHead=pCur;
pCur=pNext;
pNext=pNext->next;
}
pCur->next=pNewHead;
pNewHead=pCur;
return pNewHead;
}
//获得链表中最后一个节点
Node* get_last_node(Node* pHead)
{
Node* pCur=pHead;
if(NULL==pHead)
return NULL;
while(pCur->next)
pCur=pCur->next;
return pCur;
}
总结:链表翻转,思路简单,但是编写代码过程中,细节较多,需要注意。比如说,取出链表时,要保存它的前一个节点和后一个节点,保证逆置后,可以放回到原链表中。