1. 程式人生 > 其它 >【PAT】B1025. 反轉連結串列 (25)

【PAT】B1025. 反轉連結串列 (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(<= 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; }