链表翻转【比如链表1→2→3→4→5→6,k=2, 翻转后2→1→4→3→6→】

2.【附加题】–1、链表翻转,给出一个链表和一个数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). 提示:这个题是链表逆置的升级变型。

#include<iostream>
using namespace std;
typedef struct ListNode
{
    int data;
    ListNode* next;
    ListNode(const int& x)
        :data(x)
        ,next(NULL)
    {}
}Node;

Node* fun1(Node* PHead)//链表逆置
{
    //1.链表为空,直接返回或者链表只有一个结点,直接返回
    if (PHead==NULL||PHead->next==NULL)
    {
        return PHead;
    }
    //链表有多个结点
    Node* cur=PHead;
    Node* next=NULL;
    Node* PNewHead=NULL;
    while (cur)
    {
        next=cur->next;
        cur->next=PNewHead;
        PNewHead=cur;
        cur=next;
    }
    return PNewHead;
}

Node* fun2(Node* PHead)//获得链表最后一个结点
{
    //1.链表为空或者只有一个结点
    if (PHead==NULL||PHead->next==NULL)
    {
         return PHead;
    }
    //2.链表有多个结点
    Node* cur=PHead;
    while (cur->next)
    {
        cur=cur->next;
    }
    return cur;
}

Node* fun3(Node* PHead,int k)//链表翻转
{
    //1.如果链表为空或者只有一个结点
    if (PHead==NULL||PHead->next==NULL)
    {
        return PHead;
    }
    //2.链表有多个结点
    Node* cur=PHead;//遍历每段小链表
    Node* PNewHead=NULL;//记录每段小区间的头结点
    Node* PLastNode=NULL;//记录每段小区间的尾结点
    Node* PNextNode=NULL;//记录下一个区间的的头结点
    PHead=NULL;//记录翻转以后的链表的头0

    while (cur)
    {
        int pos=0;
        PNewHead=cur;//要翻转的小链表的头结点
        //cur走到小链表的尾端来判断该小链表的节点个数是否小于3
        while (cur&&pos<k-1)
        {
            cur=cur->next;
            pos++;
        }

        //如果cur为空,说明该段区间不够k个结点,不用翻转
        if (cur)
        {
            PNextNode=cur->next;//记录下一个小链表的头结点
            cur->next=NULL;//将该段小链表与总链表分离
            PNewHead=fun1(PNewHead);//将该段小链表逆置
            if (PLastNode==NULL)//如果是第一段小区间,则要记住链表的头,这就是链表翻转以后的头结点
            {
                PHead=PNewHead;
            }             //1.小链表逆置完以后要连接到总链表中:除了第一个小链表外,都需要分两步1.链接到前面链表2.连接到后面链表
            else//1.1除了第一个小链表之外,后面的链表都要连接到前面已经逆置好的链表的尾部;
            {
                PLastNode->next=PNewHead;
            }
            //1.2将逆置以后的小链表链接到后面的链表
            PLastNode=fun2(PNewHead);//求逆置以后的小链表的尾结点
            PLastNode->next=PNextNode;//将逆置以后的小链表连接到总链表上
            cur=PNextNode;//更新cur,开始遍历下一个链表
        }
    }
    return   PHead;
}
void Printf(Node* PHead)
{
    if (PHead==NULL)
    {
        return ;
    }
    else
    {
        Node* cur=PHead;
        while (cur)
        {
            cout<<cur->data<<" ";
            cur=cur->next;
        }
    }
}

int main()
{
    Node* node1=new Node(1);
    Node* node2=new Node(2);
    Node* node3=new Node(3);
    Node* node4=new Node(4);
    Node* node5=new Node(5);
    Node* node6=new Node(6);
    node1->next=node2;
    node2->next=node3;
    node3->next=node4;
    node4->next=node5;
    node5->next=node6;
    Printf(node1);  
    cout<<endl;
    //Node* Phead1=fun3(node1,2);
    //Printf(Phead1);

    //cout<<endl;
    //Node* Phead2=fun3(node1,3);
    //Printf(Phead2);
    //cout<<endl;
    Node* Phead3=fun3(node1,4);
    Printf(Phead3);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值