1. 程式人生 > >PAT 1025. 反轉連結串列 (25)---最後一個測試點的坑點

PAT 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
題目分析:
題目要求將k個結點進行逆轉,等於將連結串列分成了n/k段(這裡的n指的是結點的有效個數,即在連結串列上的結點),每段有k個節點,將每段逆轉過來後再連線到一塊。這種操作很容易想到先進後出的zhan,即將每一段進棧,之後在依次輸出到佇列中,重複操作每一段。直到所有段中的結點都已經進入佇列,最終將連結串列中剩餘的不夠一段的結點進入佇列。最後輸出之前記得更新結點的next,將它們重新連結在一塊。
注意點:

題目中並沒有關於所有輸入的結點都是有效的說法。。因此再輸入之後,應該從首地址遍歷整個連結串列,對連結串列上的所有結點進行計數。。。。筆者剛開始最後一個測試點老是過不去。後來查了一下,原來還有這個陷阱在。。。立馬記在小本本上。

#include<stdio.h>
#include<stack>
#include<queue>
using namespace std;
const int maxn=100000;           //定義最大連結串列結點數 
struct node{
    int address,data,next;       //結點結構體,成員有地址address,資料域data,指標域next 
}num[maxn]; int main() { int address,begin,n,k; //臨時存放結點地址的address,存放首地址的begin,結點數n,逆轉結點數k stack<node> s; //臨時存放逆轉結點的棧 queue<node> q; //存放逆轉後的序列 scanf("%d%d%d",&begin,&n,&k);//讀入 for(int i=0;i<n;i++){ scanf("%d%",&address); num[address].address =address; scanf("%d%d",&num[address].data,&num[address].next); //讀入每個結點的資訊 } int p=begin,cnt=0,count=0; //p為工作指標,cnt記錄當前已經進入棧中的逆轉結點數。count記錄有效結點數 while(p!=-1){ count++; p=num[p].next; //遍歷連結串列統計結點個數 } p=begin; //p指標回到首位 for(int i=1;i<=count/k;i++){ //逆轉次數,迴圈 while(cnt!=k*i){ //只要需要逆轉的結點數沒到時 cnt++; s.push(num[p]); //入棧 p=num[p].next; } if(cnt==k*i){ //本次逆轉完畢 while(!s.empty()){ q.push(s.top()); //將棧中所有的元素輸出到佇列中 s.pop(); } } } while(p!=-1){ //把連結串列中剩餘的不許逆轉的結點入佇列 q.push(num[p]); p=num[p].next ; } while(!q.empty()){ //輸出 node temp; temp=q.front(); q.pop(); temp.next =q.front().address; //按照逆轉後的新順序,更新結點的next if(q.size()>=1){ printf("%05d %d %05d\n",temp.address,temp.data,temp.next); } else { temp.next =-1; //最後一個結點要特別判斷 printf("%05d %d %d\n",temp.address,temp.data,temp.next); } } return 0; }