给出一个链表和一个数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。
分析可知链表翻转是链表逆置的升级变形,也可以说链表逆置是链表翻转的一个特殊情况,链表逆置相当于翻转整条链表,链表翻转相当于多次逆置部分链表,再把相应结点连接起来。
pNode ReverseList(pNode pHead, pNode pTail) //逆置
{
pNode pPrev = NULL; //pPrev为空才能断开pPrev->_next = pCur这个指向,避免出现死循环
pNode pCur = pHead;
pNode pNext = NULL;
pNode pReversedHead = NULL;
if (pHead == NULL)
return NULL;
if (pHead == pTail)
return pHead;
while (pCur != pTail)
{
pNext = pCur->_next;
pCur->_next = pPrev;
pPrev = pCur;
pCur = pNext;
}
pReversedHead = pPrev;
return pReversedHead;
}
pList RotateList(pList *pplist, size_t k) // 翻转
{
pNode pHead = *pplist;
pNode pTail = *pplist;
pNode pReversedList = NULL;
pNode pReversedTail = NULL;
pNode pReversedHead = NULL;
size_t index = 0;
size_t i = 0;
//先翻转前k个节点
for (i = 0; i < k; i++)
{
pTail = pTail->_next;
if (pTail == NULL)
break;
}
pReversedList = ReverseList(pHead, pTail); //保存指向翻转后的链表的指针
//设置接下来要翻转的k个节点的头和尾
pReversedTail = pHead;
pHead = pTail;
//翻转后续的节点
while (pTail != NULL)
{
pTail = pTail->_next;
index++;
if (pHead && (index%k == 0))
{
pReversedHead = ReverseList(pHead, pTail);
pReversedTail->_next = pReversedHead;
pReversedTail = pHead;
pHead = pTail;
}
}
if (pHead != NULL) //此时表示链表存在未翻转的节点,直接链在上一次已翻转的尾节点之后
pReversedTail->_next = pHead;
return pReversedList;
}
链表的结点结构为:
typedef int DataType;
typedef struct Node
{
DataType _data;
struct Node* _next;
}Node,*pNode,*pList; //取符合代表意义的名字