标签:
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 33218
Sample 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 100004 3 4 typedef struct List { 5 int Data; 6 int Addr; 7 int NextAddr; 8 struct List *Next; 9 }iList; 10 11 void PrintList (iList *a); 12 iList *ListReversing (iList *p,int K); 13 14 int main() 15 { 16 int FirstAddr; 17 int i; 18 int K; //反转子链长度K 19 int N; // the total number of nodes 20 int Num; //链表建好之后的节点数 21 int data[MAX]; 22 int NextAddress[MAX]; 23 int temp; 24 25 scanf("%d %d %d",&FirstAddr,&N,&K); 26 27 iList a[N+1]; 28 29 a[0].NextAddr = FirstAddr; 30 31 for(i = 0; i<N ; i++) 32 { 33 scanf("%d",&temp); 34 scanf("%d %d",&data[temp],&NextAddress[temp]); 35 } 36 37 i = 1; 38 while(1) 39 { 40 if(a[i-1].NextAddr == -1 ) 41 { 42 a[i-1].Next = NULL; 43 Num = i-1; 44 break; 45 } 46 47 a[i].Addr = a[i-1].NextAddr; 48 a[i].Data = data[a[i].Addr]; 49 a[i].NextAddr = NextAddress[a[i].Addr]; 50 a[i-1].Next = a+i; 51 52 i++; 53 } 54 55 iList *p = a; //p指向链表头结点 56 iList *rp = NULL; //反转链表函数的返回值 57 58 if(K <= Num); 59 { 60 for(i = 0;i < (Num/K) ; i++) 61 { 62 rp = ListReversing(p,K); 63 p -> Next = rp; 64 p -> NextAddr = rp -> Addr; 65 66 int j = 0; 67 while(j < K) 68 { 69 p = p-> Next; 70 j++; 71 } 72 } 73 } 74 75 PrintList(a); 76 return 0; 77 } 78 79 iList* ListReversing (iList *p,int K) 80 { 81 int count = 1; 82 iList *new = p ->Next; 83 iList *old = new ->Next; 84 iList *temp = NULL ; 85 while (count < K) 86 { 87 temp = old ->Next; 88 old ->Next = new; 89 old ->NextAddr = new ->Addr; 90 new = old; 91 old = temp; 92 count++; 93 } 94 p ->Next ->Next = old; 95 96 if(old != NULL) 97 { 98 p ->Next ->NextAddr = old ->Addr; 99 100 } 101 else 102 { 103 p ->Next ->NextAddr = -1; 104 } 105 return new; 106 } 107 void PrintList (iList *a) 108 { 109 iList *p = a; 110 while(p -> Next != NULL){ 111 p = p ->Next; 112 if (p->NextAddr != -1 ){ 113 //格式输出,%.5意味着如果一个整数不足5位,输出时前面补0 如:22,输出:00022 114 printf("%.5d %d %.5d\n", p->Addr, p->Data, p->NextAddr); 115 }else{ 116 //-1不需要以%.5格式输出 117 printf("%.5d %d %d\n", p->Addr, p->Data, p->NextAddr); 118 } 119 } 120 }
ListReversing函数不仅要交换指针,还要交换addr.
测试点一共有7个: L 代表单链表节点数,因为构成单链表的节点不一定都在输入的N个节点中,即:L<=N;
case 0:L = N 有节点 Address = 99999
case 1: L = mK, L = N, (m = 2, 3, 4,...) 有节点 Address = 99999
case 2: K = N, L = N 有节点 Address = 99999
case 3: K = 1, L = mK 有节点 Address = 99999
case 4: K = 1, L = N = 1 (很简单的一个测试点)
case 5: K != 1, L % K = (K-1) (节点数很多,如果建链表的复杂度是O(n*n), 超时的可能性很大)
case 6: L > N (有多余节点) 有节点Address = 99999
要考虑的细节:K=1不反转,K=L 全反转,L%K == 0, 每段都反转,L%k = (K-1),多余的节点不反转。L < N ,有多余节点的情况。
thanks:
PAT 02-线性结构1. Reversing Linked List
标签:
原文地址:http://www.cnblogs.com/yangRyoung/p/4626242.html