原题连接:https://www.patest.cn/contests/pat-a-practise/1074
题目:
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 (<= 105) 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 33218Sample Output:
00000 4 33218 33218 3 12309 12309 2 00100 00100 1 99999 99999 5 68237 68237 6 -1
我的代码:
1 #include<stdio.h> 2 #define Max 100000 3 typedef struct Node { 4 int Data; 5 int Next; 6 }node; 7 /* 统计节点的个数 */ 8 int CountNodes(node *list,int Plist) //因为题目中有多余的节点,故要统计节点个数 9 { 10 int cnt=1; 11 while((Plist=list[Plist].Next)!=-1)cnt++; 12 return cnt; 13 } 14 /*输入函数 */ 15 void Input(node *list,int n,int Plist) 16 { 17 int i,addr,Data,Next; 18 for (i=1;i<=n;i++) //利用数组模拟节点! 19 { 20 scanf("%d%d%d",&addr,&Data,&Next); //不必按照顺序输入,是因为只要有“头节点”,就可以找到其他元素了 21 list[addr].Data=Data; 22 list[addr].Next=Next; //输入完成后,即形成了一个单向链表 23 } 24 } 25 /* 逆序函数 */ 26 int Reverse(node *list,int Plist,int cnt,int k) 27 { 28 int prevNode,currNode,nextNode; //三个基本要素 29 prevNode=-1; 30 currNode=Plist; 31 nextNode=list[currNode].Next; 32 int i,j; 33 int lasthead,head=-1; 34 for (j=0;j<cnt/k;j++) //分为 cnt/k 段进行逆序,每段k个节点 。后面的余数不必逆序 35 { 36 lasthead=head; //前一段逆序好的末尾节点 37 head=currNode; //逆序好的该段的末尾节点 38 for (i=0;i<k;i++) 39 { // 单链表逆序的基本模板! 40 list[currNode].Next=prevNode; 41 prevNode=currNode; 42 currNode=nextNode; 43 nextNode=list[nextNode].Next; 44 } 45 if (j==0)Plist=prevNode; //整个逆序好的链表的第一个节点 46 else list[lasthead].Next=prevNode; //前一段的尾节点和其下一段的头节点 对上! 47 } 48 list[head].Next=currNode; //进行逆序的最后一段的末尾节点和剩余没有进行逆序的段的头节点 对上! 49 return Plist; 50 } 51 void Printlist(node *list,int Plist) 52 { 53 while((list[Plist].Next)!=-1){ 54 printf("%05d %d %05d ",Plist,list[Plist].Data,list[Plist].Next); 55 Plist=list[Plist].Next;} 56 printf("%05d %d %d ",Plist,list[Plist].Data,list[Plist].Next); 57 } 58 int main() 59 { 60 int Plist,n,k; 61 node list[Max]; 62 scanf("%d%d%d",&Plist,&n,&k); 63 Input(list,n,Plist); 64 int cnt; 65 cnt=CountNodes(list,Plist); 66 Plist=Reverse(list,Plist,cnt,k); 67 Printlist(list,Plist); 68 return 0; 69 }