1. 程式人生 > 實用技巧 >簡單資料結構

簡單資料結構

簡單資料結構

單鏈表

1、用途

快速維護資料的新增與刪除

2、原理

每個節點由資料與指標兩部分組成,指標指向該節點後一個元素所在的位置。

頭指標指向連結串列的第一個元素。如果有尾指標的話尾指標指向連結串列的最後一個元素。

利用陣列模擬連結串列,原因是new操作太慢。

3、複雜度

插入/刪除:\(O(1)\)

查詢/遍歷:\(O(n)\)

4、模板

初始化
const int MAXN = 1e5 + 10;
int e[MAXN], ne[MAXN], idx = 0;
ne[0] = -1;

注意:

\(0\)號節點作為頭指標,裡面不放值,只存放第一個元素開始的地址;

\(e[i]\)表示地址為\(i\)

的元素的值,\(ne[i]\)表示地址為\(i\)的元素後一個元素的地址;

③以\(-1\)作為連結串列結束的標誌。

新增元素
e[++idx] = x, ne[idx] = ne[0], ne[0] = idx;

注意:

①該模板在連結串列頭新增元素。

e[++idx] = x, ne[idx] = ne[k], ne[k] = idx;

注意:

①該模板在連結串列指定位置後新增元素。

刪除元素
ne[k] = ne[ne[k]];

注意:

①該模板在連結串列指定位置後刪除元素。

遍歷連結串列
for (int i = ne[0]; i != -1; i = ne[i]) cout << e[i] << ' ';

5、備註

①若需要建立多個連結串列則需要使用\(h\)陣列記錄每個連結串列頭結點的地址。

1、用途

維護一個先進後出的序列

2、原理

利用top指標,加入元素時++top,把元素放入新開闢的空間內;刪除時--top,把棧頂元素彈出。

3、複雜度

新增/刪除/訪問棧頂元素:\(O(1)\)

4、模板

初始化
const int MAXN = 1e5 + 10;
int st[MAXN], top = 0;
新增元素
st[++top] = x;
刪除元素
--top;
訪問棧頂元素
return st[top];
判斷棧是否為空
if (!top) return "empty";
else return "not empty";

5、備註

①在刪除元素或訪問棧頂元素的時候要先判斷棧是否為空。

佇列

1、用途

維護一個先進先出的序列

2、原理

利用頭尾指標,加入元素時++r,把元素放入新開闢的空間內;刪除時++l,把隊首元素彈出。

3、複雜度

新增/刪除/訪問隊首隊尾元素:\(O(1)\)

4、模板

初始化
const int MAXN = 1e5 + 10;
int que[MAXN], l = 1, r = 0;
新增元素
que[++r] = x;
刪除元素
++l;
訪問隊首元素
return que[l];
訪問隊尾元素
return que[r];
判斷佇列是否為空
if (l > r) return "empty";
else return "not empty";

5、備註

①在刪除元素或訪問隊首/隊尾元素的時候要先判斷佇列是否為空。

單調棧

1、用途

維護某個元素之前/之後第一個滿足某條件的數

2、原理

在棧的基礎上保證棧內元素的有序性

3、複雜度

新增/刪除/訪問棧頂元素:\(O(1)\)

4、模板

初始化
const int MAXN = 1e5 + 10;
int st[MAXN], top = 0;

注意:

①單調棧記憶體放的是該元素在原陣列中的下標。

新增元素
while (top && check(st[top], i)) --top;
//此時st[top]為i前第一個滿足某性質元素的下標
st[++top] = i;
刪除元素
--top;
訪問棧頂元素
return st[top];
判斷棧是否為空
if (!top) return "empty";
else return "not empty";

5、備註

①在刪除元素或訪問棧頂元素的時候要先判斷棧是否為空。

單調佇列

1、用途

維護某個長度固定的區間內滿足某條件的數

2、原理

在雙端佇列的基礎上保證佇列內元素的有序性

3、複雜度

新增/刪除/訪問隊首隊尾元素:\(O(1)\)

4、模板

初始化
const int MAXN = 1e5 + 10;
int que[MAXN], l = 1, r = 0;

注意:

①單調佇列記憶體放的是該元素在原陣列中的下標。

新增元素
while (l <= r && check(que[r], i)) --r;
while (l <= r && que[l] <= i - k) ++l;
que[++r] = i;
if (i >= k) ... //此時que[l]為區間內滿足某條件的數,對其進行操作
刪除隊首元素
++l;
刪除隊尾元素
--r;
訪問隊首元素
return que[l];
訪問隊尾元素
return que[r];
判斷佇列是否為空
if (l > r) return "empty";
else return "not empty";

5、備註

①在刪除元素或訪問隊首/隊尾元素的時候要先判斷佇列是否為空。

例題

牛客2020暑期多校2 F Fake Maxpooling

HDU 6759 Leading Robots