1025 反转链表 (25 分)

题目链接:1025 反转链表 (25 分)

 

这道题目花费了很长时间,主要是最近事情太多,没有集中精力想这道题目。

起初我将address和Next按照字符串处理,这样处理的好处是不用考虑整数的前导0。但是提交后有一个测试点超时,

我赶紧将cout换成printf,将输出的字符串进行.c_str();再一次提交,没有超时,AC!。但是字符串我还是很生疏的,

我不小心将cin.ignore();删除之后,程序继续超时,字符串的输入输出及其基本操作我还是很迷的。暂且搁置,以后

好好整理,于是我将输入输出换成整数int,又重新捋了一下逻辑。

假定要求反转区间长度为k,该程序设置了一个计数器i,初值为0,每当访问一个结点,计数器++,每当k是i的整数倍时,

对区间k个结点进行反转。具体反转进行一下操作。

1、newhead记录本次反转之后的区间的新的首元结点,若不是第一次反转,将上一区间的尾元结点与新的首元结点连接,即连接两个区间。

newtail记录区间调整后的尾元结点,end记录尾元结点的下一个结点,当作区间for循环的终止条件。如果是第一次进行调整,则更新整个链表的

首元结点。

2、对区间进行调整的思想如下

temp的初值记录紧跟着本曲间的第一个结点,进行区间反转时,从原区间的head开始,到head为止(不包含end),依次更新其Next。特别注意,

在更行每一个address的Next之前记录其Next(next记录),不然不能按照原区间顺序进行更新。另外head的Next应当更新为temp的初值。更新完

毕后记着更新head,每一次区间调整的head即为上一次的end,第一个的head为first。

3、最后输出的时候注意-1的特殊情况。

 

 

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 struct Node
 5 {
 6     int Data,Next;
 7 }a;
 8 map<int,Node> m;
 9 int main()
10 {
11     int address,next,first,head,end,tail,newhead,newtail,add,data,n,k;
12     scanf("%d %d %d",&first,&n,&k);//结点总个数n,要求反转的结点数k
13     newtail=-2;
14     for(int i=1;i<=n;i++)
15     {
16         scanf("%d %d %d",&address,&a.Data,&a.Next);
17         m[address]=a;
18     } 
19     int i=0;
20     head=first;
21     for(address=first;address!=-1;address=m[address].Next)
22     {
23         i++;
24         if(i%k==0)
25         {
26             newhead=address;        //区间调整后的首结点 
27             if(newtail!=-2)
28                 m[newtail].Next=newhead; 
29             newtail=head;            //区间调整后的尾结点
30             end=m[address].Next; 
31             address=newtail;         //区间调整后的最后一个结点,避免影响for循环逻辑
32             if(i/k==1)
33                 first=newhead;        //如果是第一次进行调整,更新新的首元结点 
34             int temp=end;    //temp初值记录原区间尾元结点的Next 
35 //从原来的第一个结点开始,依次调整它们的Next,注意新区间的首元结点的Next应当调整为原区间尾元结点的Next。
36             for(add=head;add!=end;temp=add,add=next)
37             {
38                 next=m[add].Next;
39                 m[add].Next=temp;
40             }     
41             head=end;//head记录没有调整的区间的第一个结点的地址。    
42         }    
43     }
44     for(address=first;address!=-1;address=m[address].Next)
45         if(m[address].Next!=-1)
46             printf("%05d %d %05d\n",address,m[address].Data,m[address].Next);
47         else
48             printf("%05d %d %d\n",address,m[address].Data,m[address].Next);
49     return 0;
50 } 
51 /*
52 00100 6 3
53 00000 4 99999
54 00100 1 12309
55 68237 6 -1
56 33218 3 00000
57 99999 5 68237
58 12309 2 33218
59 */

 

转载于:https://www.cnblogs.com/ManOK/p/10215595.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值