給定一個常數 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 (≤)、以及正整數 K (≤),即要求反轉的子鏈結點的個數。結點的地址是 5 位非負整數,NULL 地址用 − 表示。
接下來有 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 <map> #include <algorithm> #include <iostream> #include <string> #include <math.h> #include <vector> using namespace std; const int maxn = 100010; struct node{ int addr; int data; int next; }nodes[maxn]; vector<node> v; int main(){ int st, n, k, count = 0; cin >> st >> n >> k; for (int i = 0; i < n; i++){ int start, data, next; cin >> start >> data >> next; nodes[start].addr = start; nodes[start].data = data; nodes[start].next = next; } while (st != -1){ v.push_back(nodes[st]); st = nodes[st].next; count++; } for (int i = 0; i+k <= count; i = i + k){ reverse(v.begin() + i, v.begin() + i + k); } for (int i = 0; i < count-1; i++){ v[i].next = v[i + 1].addr; } v[count-1].next = -1; for (int i = 0;i < count-1; i++){ printf("%05d %d %05d\n", v[i].addr, v[i].data, v[i].next); } printf("%05d %d %d\n", v[count - 1].addr, v[count - 1].data, v[count - 1].next); system("pause"); }
一開始鏈表結構體里沒有設置addr屬性,直接根據下標來,后面發現這個反轉輸出還要自身地址和下一個地址,不單單是data就好,不設置addr屬性就會很難辦,而且由於不是所有輸入都在鏈表上,還是需要addr。中間有想過加個rank屬性對其進行排序反轉,發現一開始的單一數組還是不能實現,排完序后地址都亂了。然后開始想最笨的鏈表一點點實現,發現頭尾處理起來非常麻煩,一段的結尾指針要指向另一段反轉過的地址,從尾巴開始處理可能會好一點。這時就想去求助網上大神了,一看其實我一開始的排序想法其實也是可以的,只需要多開一個數組,存放整個node而不是只有data就好了,反轉過后的next只要再迭代一遍新數據就得到了。
注意點:存好結構體后,新開一個數組存放鏈表結構數據,順便把不在鏈表上的數據排除,然后直接就可以對數組反轉,更新一下next就ok了。還有就是結構體一定要存放自己的地址這個屬性。