链表翻转

题目:

链表翻转。给出一个链表和一个数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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值