【PAT】B1025. 反轉連結串列 (25)
阿新 • • 發佈:2021-01-21
給定一個常數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(<= 10^5)、以及正整數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
解單鏈表題目的5步曲:
1.定義(靜態連結串列)
2.初始化
3.遍歷
4.排序
5.處理並輸出
在看了柳神的解法後得知該題做得簡便的要點是使用algorithm庫中的reverse函式,然後我結合了演算法筆記總結出的5步法做了個改寫
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn = 100010;
//1.定義
struct node{
int address;
int data;
int next;
int order;
node(){
order = maxn;//2.初始化
}
}nd[maxn];
bool cmp(node a,node b){
return a.order < b.order;
}
int main(){
int fir, n, k,addr;
scanf("%d%d%d", &fir, &n, &k);
for (int i = 0; i < n; ++i){
scanf("%d", &addr);
scanf("%d%d", &nd[addr].data, &nd[addr].next);
nd[addr].address = addr;
}
//3.遍歷
int count = 0, p = fir;
while (p != -1){
nd[p].order = count;
count++;
p = nd[p].next;
}
sort(nd, nd + maxn, cmp);//4.排序
for (int i = 0; i < (count - count%k); i += k){
reverse(nd + i, nd + i + k);//5.處理
}
//輸出
for (int i = 0; i < count-1; ++i){
printf("%05d %d %05d\n", nd[i].address, nd[i].data, nd[i + 1].address);
}
printf("%05d %d -1\n", nd[count-1].address, nd[count-1].data);
return 0;
}