1074 Reversing Linked List

在这里插入图片描述在这里插入图片描述

题目大意:

给你一个链表,每隔k个节点翻转一下,输出翻转后的结果。

解题思路:

如果链表的长度正好是K的整数倍则全部要分段翻转,否则末尾的余数部分无需翻转。重点是翻转部分首尾指针的修改,可以定义一个变量保存未翻转前尾指针的下一个节点地址,每间隔K个节点修改首指针的指向地址。其他节点就反向修改即可。
代码如下:

#include<iostream>
#include<cstdio>
#include<fstream>
#include<set>
#include<cmath>
#include<cstring>
#include<string>
#include<map>
#include<vector>
#include<iomanip>
#include<cstdlib>
#include<list>
#include<queue>
#include<stack>
#include<algorithm>
#define inf 0x3f3f3f3f
#define MOD 1000000007
#define mem0(a) memset(a,0,sizeof(a))
#define mem1(a) memset(a,-1,sizeof(a))
#define meminf(a) memset(a,inf,sizeof(a))
//vector ::iterator it;
//set<int>::iterator iter;
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
struct lis1//保存原有节点
{
  int key,next;
}nod1[110000];
struct lis2//保存筛选后的节点
{
  int address,key,next;
}nod2[110000];
int main()
{
  int a1,d1,n1;
  scanf("%d %d %d",&a1,&d1,&n1);
  for(int i=0;i<d1;i++)
  {
    int t1,t2,t3;
    scanf("%d %d %d",&t1,&t2,&t3);
    nod1[t1].key=t2;nod1[t1].next=t3;
  }
  int tmp=a1,num=0;
  while(tmp!=-1)//从给定头指针遍历后得到的链表,将节点依次放入
  {
    nod2[num].address=tmp;nod2[num].key=nod1[tmp].key;
    nod2[num].next=nod1[tmp].next;num++;
    tmp=nod1[tmp].next;
  }
  int k1,k2,k3;
  if(num%n1)//有余数,也末尾部分无需翻转
  {
    int sum=num-num%n1;//需要翻转部分的末尾
    k1=nod2[sum].address,k2=sum-1;//分别是末尾节点的指针,开始翻转节点的下标
  }
  else//都要翻转
  {
    k1=-1;k2=num-1;k3=k2;
  }
  while(k2>=0)//遍历链表
  {
    if(k2%n1)
    {
      nod1[nod2[k2].address].next=nod2[k2-1].address;//反向修改指针
    }
    else//翻转了K个,修改首尾节点指针
    {
      nod1[nod2[k2].address].next=k1;
      k1=nod2[k3].address;
      k3=k2-1;//保留翻转部分的头指针
    }
    k2--;
  }
  int add=nod2[n1-1].address;//翻转后的头指针
  while(add!=-1)
  {
    if(nod1[add].next!=-1)
    printf("%05d %d %05d\n",add,nod1[add].key,nod1[add].next);
    else printf("%05d %d -1\n",add,nod1[add].key);
    add=nod1[add].next;
  }
//  cin.tie(0);
//  freopen("test.txt","r",stdin);
//  freopen("output.txt","w",stdout);
 return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值