链表翻转

来源:互联网 发布:消费者协会网络投诉 编辑:程序博客网 时间:2024/06/05 08:28

题目:

链表翻转。给出一个链表和一个数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。先把每个小链表完成逆置。
第二步把每个小链表的尾首相连起来。
如图:
这里写图片描述

细节问题

这里写图片描述
K对于链表来说分俩种情况:
第一种就是链表大小刚好够分成大小为K的几个小链表。
第二种就是链表大小不足以刚好划分为大小为K的小链表,即第一个小链表可能够分,但是到了第二个的时候剩余的节点不够划分为大小为K的小链表了,上图就是这俩种情况。
所以对于第一种刚好够分,start end 这俩个界限的指针最终都走向NULL,对于不够分start最终非NULL。
那么我们就要最后把start入Phead队列,以便上一链表的尾连向它。

代码

Node* RotateList(Node* list, size_t k){    assert(list != NULL&&k > 0);    if (list->_PNext == NULL)    {        if (k > 1) {            cerr << "k值大于链表长度" << endl;            exit(1);        }        return list;    }    queue<Node*> qhead;    queue<Node*> qtail;    Node*start = list;    Node*end = start;//尾随位置    Node*ppre = list;    Node*pCur = ppre->_PNext;    Node*Next = pCur->_PNext;    int  step = k;    while (end!=NULL&&step-- > 0)    {        end = end->_PNext;    }    if (end == NULL)    {        cerr << "k值大于链表长度" << endl;        exit(1);    }    step = k;    while (start != NULL)    {        qtail.push(ppre);        while (pCur!=NULL)        {            pCur->_PNext = ppre;            ppre = pCur;            pCur = Next;            if(Next!=NULL)Next = Next->_PNext;            if (ppre==end||pCur == end) break;        }        if (pCur == end)        {            qhead.push(ppre);        }        start = end;        if (end == NULL) break;//能进来end肯定不为空        ppre = end;        pCur = ppre->_PNext;//end不为空,但pCur是end的下一个,它有可能为空        if (pCur != NULL)Next = pCur->_PNext;        step = k;        while (end != NULL&&step-- > 0)        {            end = end->_PNext;        }        if (step>0) break;    }    if(start!=NULL)qhead.push(start);//说明长度没正好够走完。    Node*ret = qhead.front();    qhead.pop();    Node*phead = NULL;    Node*ptail = NULL;    while (!qhead.empty())    {        ptail= qtail.front();        qtail.pop();        phead = qhead.front();        qhead.pop();        ptail->_PNext = phead;    }    if (!qtail.empty())//到这分俩种情况 第一种 整个链表长度刚好够分几个小块 ,这时qtail内还剩下最后一个节点.    {                   //第二种如果不够分几个小块,也就是说end不是正好走到NULL而是因为链表长度不够了走到NULL的时候K还大于0,此时qtail走到这里为空        ptail = qtail.front();        ptail->_PNext = NULL;    }    return ret;}