題目描述
實現一個單鏈表,鏈表初始爲空,支持三種操作:
(1) 向鏈表頭插入一個數;
(2) 刪除第k個插入的數後面的數;
(3) 在第k個插入的數後插入一個數
現在要對該鏈表進行M次操作,進行完所有操作後,從頭到尾輸出整個鏈表。
注意:題目中第k個插入的數並不是指當前鏈表的第k個數。例如操作過程中一共插入了n個數,則按照插入的時間順序,這n個數依次爲:第1個插入的數,第2個插入的數,…第n個插入的數。
輸入格式
第一行包含整數M,表示操作次數。
接下來M行,每行包含一個操作命令,操作命令可能爲以下幾種:
(1) “H x”,表示向鏈表頭插入一個數x。
(2) “D k”,表示刪除第k個輸入的數後面的數(當k爲0時,表示刪除頭結點)。
(3) “I k x”,表示在第k個輸入的數後面插入一個數x(此操作中k均大於0)。
輸出格式
共一行,將整個鏈表從頭到尾輸出。
數據範圍
1≤M≤100000
所有操作保證合法。
輸入樣例:
10
H 9
I 1 1
D 1
D 0
H 6
I 3 6
I 4 5
I 4 5
I 3 4
D 6
輸出樣例:
6 4 6 5
1.單鏈表的簡單介紹
單鏈表是一種鏈式存取的數據結構,用一組任意地址空間(地址空間即存儲單元)來存放線性表的數據元素。單鏈表中的數據是以節點的形式來表示,而節點是用結構體來描述,每個節點都是由元素和指針構成,即該結構體中包含兩個成員變量:存放元素的成員變量和存放下一個節點地址的成員變量。
2.順序表與鏈表的區別
順序表的特點爲:邏輯相鄰的兩節點其物理地址也是相鄰的;鏈表的特點爲:邏輯相鄰的兩節點其物理地址不相鄰。順序表的存儲方式是:節點元素連續存放在存儲單元;鏈表的存儲方式是:節點元素隨機存放在存儲單元。
鏈表的插入和刪除操作:
代碼如下:
#include<iostream>
using namespace std;
const int N = 1e6 + 10;
int head; //表示頭結點
int idx; //表示當前是第幾個數
int e[N]; //表示第i個數所存儲的值
int ne[N]; //i的下一個節點
void init()
{
head = -1; //初始化
idx = 0; //下標從0開始
}
//插入到頭結點
//1.先用e[idx]存儲該值
//2.將ne[idx]即第idx個數的下一個節點指向頭結點
//3.頭結點head更新爲idx;
//4.idx++;
void add_to_head(int x)
{
e[idx] = x, ne[idx] = head, head = idx, idx++;
}
// 將x插入到第k個數的後面
//1.先用e[idx]存儲該值x
//2.將ne[idx]即第idx個數的下一個節點指向第k個數的下一個節點
//3.將ne[k]指向idx;
//4.idx++;
void add(int k, int x)
{
e[idx] = x, ne[idx] = ne[k], ne[k] = idx, idx++;
}
//刪除第k個數後面的數
//直接讓ne[k] = ne[ne[k]]即可
void move(int k)
{
ne[k] = ne[ne[k]];
}
int main()
{
int t;
init();
cin >> t;
while(t--){
char c;
int k, x;
cin >> c;
if(c == 'H'){
cin >> x;
add_to_head(x);
}
else if(c == 'D'){
cin >> k;
if(!k)head = ne[head]; //如果k == 0, 要刪除頭結點,即讓head等於下一個節點
else move(k - 1);
}
else if(c == 'I'){
cin >> k >> x;
add(k - 1, x);
}
}
for(int i = head; i != -1; i = ne[i])
cout << e[i] << ' ' ;
cout << endl;
return 0;
}