1. 程式人生 > 其它 >1025 反轉連結串列 (25 分)

1025 反轉連結串列 (25 分)

1025 反轉連結串列 (25 分)

給定一個常數K以及一個單鏈表L,請編寫程式將L中每K個結點反轉。例如:給定L為 1→2→3→4→5→6,K為 3,則輸出應該為 3→2→1→6→5→4;如果K為 4,則輸出應該為 4→3→2→1→5→6,即最後不到K個元素不反轉。

輸入格式:

每個輸入包含 1 個測試用例。每個測試用例第 1 行給出第 1 個結點的地址、結點總個數正整數N(105)、以及正整數K(N),即要求反轉的子鏈結點的個數。結點的地址是 5 位非負整數,NULL 地址用1表示。

接下來有N行,每行格式為:

Address Data Next

其中Address是結點地址,Data是該結點儲存的整數資料,Next是下一結點的地址。

輸出格式:

對每個測試用例,順序輸出反轉後的連結串列,其上每個結點佔一行,格式與輸入相同。

輸入樣例:

00100 6 4
00000 4 99999
00100 1 12309
68237 6 -1
33218 3 00000
99999 5 68237
12309 2 33218
結尾無空行

輸出樣例:

00000 4 33218
33218 3 12309
12309 2 00100
00100 1 99999
99999 5 68237
68237 6 -1
結尾無空行 思路:分別構建兩個反轉前,反轉後的陣列,以每一組資料的第一個地址為陣列下標,存到反轉前陣列中;    將反轉前陣列根據最後一個地址進行儲存到反轉後的陣列;    進行反轉,反轉便是進行頭尾交換;    輸出的時候注意要改一下每一組資料的最後一個地址
#include <stdio.h>
#include 
<string.h> typedef struct{ int addr; int num; int Next; }List; int main(){ List L[100000],sort[100000];//定義兩個陣列 int x,k,data,addr,b; scanf("%d%d%d",&addr,&x,&k); for(int i=1;i<=x;i++){ List temp; scanf("%d%d%d",&temp.addr,&temp.num,&temp.Next); L[temp.addr]
=temp;//以第一個地址addr為陣列下標存到反轉前陣列 } for(int i=0;i<x;i++){ sort[i]=L[addr];//根據第三個地址按順序一個一個存到反轉後陣列 addr=L[addr].Next; if(addr==-1){//防止在中間就出現間斷節點,出現便結束 x=i+1; break; } } for(int i=0;i<x/k;i++){//反轉次數 for(int j=0;j<k/2;j++){ List temp; temp=sort[j+k*i];//進行頭尾交換,反轉 sort[j+k*i]=sort[k-1-j+i*k]; sort[k-1-j+i*k]=temp; } } for(int i=0;i<x;i++){ if(i!=x-1){ sort[i].Next=sort[i+1].addr;//這就是修改最後一個地址 printf("%05d %d %05d\n",sort[i].addr,sort[i].num,sort[i].Next);//由於定義的是整型,所以要進行格式控制 } else{ sort[i].Next=-1; printf("%05d %d %d",sort[i].addr,sort[i].num,sort[i].Next); } } }