C++學習——連結串列
連結串列是一種物理儲存單元上非連續、非順序的儲存結構。連結串列由一系列結點(連結串列中每一個元素稱為結點)組成,每個結點包括兩個部分:一個是儲存資料元素的資料域,另一個是儲存下一個結點地址的指標域。
優點: 使用連結串列結構不需要預先知道資料大小,可以充分利用計算機記憶體空間,實現靈活的記憶體動態管理,連結串列還允許插入和移除表上任意位置上的節點。
缺點: 連結串列失去了陣列隨機讀取的優點,同時連結串列由於增加了結點的指標域,空間開銷比較大。
分類: 單向連結串列,雙向連結串列以及迴圈連結串列
圖示:
以下是一道例題
UVa11988:悲劇文字
題目
You’re typing a long text with a broken keyboard. Well it’s not so badly broken. The only problem with the keyboard is that sometimes the “home” key or the “end” key gets automatically pressed (internally).
You’re not aware of this issue, since you’re focusing on the text and did not even turn on the monitor! After you finished typing, you can see a text on the screen (if you turn on the monitor).
Input
There are several test cases. Each test case is a single line containing at least one and at most 100,000 letters, underscores and two special characters ‘[’ and ‘]’. ‘[’ means the “Home” key is pressed internally, and ‘]’ means the “End” key is pressed internally. The input is terminated by end-of-file (EOF). The size of input file does not exceed 5MB.
For each case, print the Beiju text on the screen.
翻譯
你在用壞了的鍵盤打一個長文字。嗯,它沒那麼壞。鍵盤的唯一問題是,有時會自動按下“home”鍵或“end”鍵。
你沒有意識到這個問題,因為你專注於文字,甚至沒有開啟顯示器!輸入完畢後,您可以在螢幕上看到文字(如果您開啟顯示器)。
在中文裡,我們可以叫它悲劇。你的任務是找到這段悲劇文字。
輸入
有幾組測試資料。每個測試用例是一行,包含至少一個且最多100000個字母、下劃線和兩個特殊字元“[”和“]”。“[”表示內部按下“Home”鍵,“]”表示內部按下“End”鍵。輸入在檔案末尾(EOF)終止。輸入檔案的大小不超過5MB。
輸出
對於每組資料,在螢幕上列印悲劇文字。
分析
用一個next陣列表示每一個字元的下一項,比如第一個字元s[1]的下一個是s[2],則next[1]=2。為了方便起見,我們還可以在連結串列的第一個元素前放一個虛擬節點,從第一個下標開始儲存資料。
我們可以設定一個游標cur,代表著位置i的字元應該插入在cur的右側。程式執行時,cur有時會跳至左端即cur=0;有時要回到右端,所以還需要開一個last變數儲存最右端的下標,使cur能通過cur=last跳回右端。
參考程式
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 100000 + 5;
int last, cur;
char s[maxn];
int next[maxn];
int main() {
while(scanf("%s", s + 1) == 1) { //輸入
int n = strlen(s + 1);
last = 0;
cur = 0;
next[0] = 0;
for(int i = 1; i <= n; i++) {
char c = s[i];
if(c == '[') {
cur = 0;
} else if(c == ']') {
cur = last;
} else {
//插入c
next[i] = next[cur];
next[cur] = i;
if(cur == last) {
last = i; //更新最後字元的編號
}
cur = i; //移動游標
}
}
for(int i = next[0]; i != 0; i = next[i]) {
printf("%c", s[i]);
}
printf("\n");
}
return 0;
}