7-2 Reversing Linked List (25分)
Given a constant K and a singly linked list L, you are supposed to reverse the links of every K elements on L. For example, given L being 1→2→3→4→5→6, if K=3, then you must output 3→2→1→6→5→4; if K=4, you must output 4→3→2→1→5→6.
Input Specification:
Each input file contains one test case. For each case, the first line contains the address of the first node, a positive N (≤10^5) which is the total number of nodes, and a positive K (≤N) which is the length of the sublist to be reversed. The address of a node is a 5-digit nonnegative integer, and NULL is represented by -1.
Then N lines follow, each describes a node in the format:
Address Data Next
where Address is the position of the node, Data is an integer, and Next is the position of the next node.
Output Specification:
For each case, output the resulting ordered linked list. Each node occupies a line, and is printed in the same format as in the input.
Sample Input:
00100 6 4
00000 4 99999
00100 1 12309
68237 6 -1
33218 3 00000
99999 5 68237
12309 2 33218
Sample Output:
00000 4 33218
33218 3 12309
12309 2 00100
00100 1 99999
99999 5 68237
68237 6 -1
#include<iostream>
#include<cstdio>
using namespace std;
#define MAX 100000
struct LNode
{
int addr;
int data;
int next;
};
typedef struct LNode List;
List L[MAX];
void printList(int addr0)
{
//cout<<"输出链表:"<<endl;
int addr=addr0;
while(L[addr].next!=-1)
{
printf("%05d %d %05d\n",L[addr].addr,L[addr].data,L[addr].next);
addr=L[addr].next;
}
printf("%05d %d %d\n",L[addr].addr,L[addr].data,L[addr].next);
}
int needReverse(int head,int k)
{
int i;
for(i=1;L[head].next!=-1;head=L[head].next)
{
i++;
if(i==k) return 1; //集齐了k个节点,这k个节点需要翻转
}
return 0;
}
int reverse(int head,int k)
{
int newhead,nexthead,next;
newhead=head;
nexthead=L[newhead].next;
int cnt=1;
while(cnt<k) //k至少为2才进行翻转
{
next=L[nexthead].next;
L[nexthead].next=newhead;
newhead=nexthead;
nexthead=next;
cnt++;
}
L[head].next=nexthead;
return newhead;
}
int reverseList(int addr0, int k)
{
int addrwait=addr0;
int addr0after;
int addrrear;
if(needReverse(addrwait,k))
{
addr0after=reverse(addrwait,k); //翻转后的表头
addrrear=addrwait; //翻转后的表尾
addrwait=L[addrrear].next; //下一个待判断是否要翻转的表头
}
else return addr0; //总的节点数小于k个,不翻转,返回最初的表头
while(needReverse(addrwait,k))
{
L[addrrear].next=reverse(addrwait,k); //上次翻转后的表尾->本次翻转后的表头
addrrear=addrwait; //记录本次翻转后的表尾(也就是翻转之前的表头)
addrwait=L[addrrear].next; //下一个待判断是否要翻转的表头
}
return addr0after; //返回新的表头(第一次翻转后的表头)
}
int main()
{
int addr0;
int total,k;
cin>>addr0>>total>>k;
int addr,data,next;
while(total--)
{
cin>>addr>>data>>next;
L[addr].addr=addr;
L[addr].data=data;
L[addr].next=next;
}
//printList(addr0);
printList(reverseList(addr0, k));
return 0;
}