Linked-List
๐ซ @TODO
Linked-List ์ฐ๊ฒฐ ๋ฆฌ์คํธ
(ํน์ List ๋ฆฌ์คํธ)
์์๋ฅผ ์ ์ฅํ ๋ ๊ทธ ๋ค์ ์์๊ฐ ์๋ ์์น๋ฅผ ํฌํจ์ํค๋ ๋ฐฉ์์ผ๋ก ์ ์ฅํ๋ ์๋ฃ๊ตฌ์กฐ
์์๋ค์ ์ด๊ณณ ์ ๊ณณ์ ํฉ์ด์ ธ์๋ค.
ํฉ์ด์ ธ์๊ธฐ์ ์ํ๋ ์์๊ฐ ์ด๋์ ์๋์ง ์ ์ ์์
์ด๋ฅผํ
๋ฉด ๋ง์ง๋ง ์์๊ฐ ๋ญ์ง ๋ฐ๋ก ์ ์ ์์
๋ชจ๋ ์์๋ฅผ ํ ๋ฒ ์ฉ ์ฝ์ด์ผ ํ๋ค๋ฉด ์ฐ๊ฒฐ ๋ฆฌ์คํธ๊ฐ ์ข์ง๋ง,
ํน์ ํ ์์ ํ๋๋ง ์๊ณ ์ถ๋ค๋ฉด ์ฐ๊ฒฐ ๋ฆฌ์คํธ๋ ์ต์
์์ฐจ ์ ๊ทผ Sequential Access
๊ทน์ฅ์์ ์๋ก ํฉ์ด์ ธ์ ์ํ๋ณด๊ธฐ
์๋ก ์ด๋์๋์ง๋ ์
๐ซง _
- ์ฑ์ง
- k๋ฒ์งธ ์์๋ฅผ ํ์ธ/๋ณ๊ฒฝํ๊ธฐ ์ํด O(k)๊ฐ ํ์ํจ
- ์์์ ์์น์ ์์๋ฅผ ์ถ๊ฐ/์์ ์์น์ ์์ ์ ๊ฑฐ๋ O(1)
- ์ถ๊ฐ, ์ ๊ฑฐํ ์์น๋ฅผ ์๊ณ ์๋ค๋ (์ด๋ฏธ ์ ๊ทผํด ์๋ค๋) ๊ฒ์ ์ ์ ๋ก
- ์๋๋ผ๋ฉด readํ๋ ๋งํผ์ ์๊ฐ ๋ณต์ก๋๊ฐ ๋ ๋ค๊ฒ ์ฃ (+O(k))
- ์์๋ค์ด ๋ฉ๋ชจ๋ฆฌ ์์ ์ฐ์ํด์์ง ์์ Cache hit rate๊ฐ ๋ฎ์ง๋ง ํ ๋น์ด ๋ค์ ์ฌ์
- ์ข
๋ฅ
- ๋จ์ผ ์ฐ๊ฒฐ ๋ฆฌ์คํธ Singly Linked List
- ์ด์ค ์ฐ๊ฒฐ ๋ฆฌ์คํธ Doubly Linked List (STL list)
- ์ํ ์ฐ๊ฒฐ ๋ฆฌ์คํธ Circular Linked List
- ํํ โ
- ์ํ โ
์ฒซ ๋ฒ์งธ ์์, ๋ ๋ฒ์งธ ์์๋ฅผ ์๋ณํ ์ ์์
๋ฐฐ์ด๊ณผ ๋ง์ฐฌ๊ฐ์ง๋ก ์ ํ ์๋ฃ๊ตฌ์กฐ
ํธ๋ฆฌ, ๊ทธ๋ํ, ํด์ฌ ๋ฑ์ ๋น์ ํ ์๋ฃ๊ตฌ์กฐ
ย | ๋ฐฐ์ด | ์ฐ๊ฒฐ ๋ฆฌ์คํธ |
k๋ฒ์งธ ์์์ ์ ๊ทผ | O(1) | O(k) |
์์ ์์น์ ์์ ์ถ๊ฐ/์ ๊ฑฐ | O(N) | O(1) (์ถ๊ฐ/์ ๊ฑฐํ ์์น๋ฅผ ์๊ณ ์๋ ๊ฒฝ์ฐ) |
๋ฉ๋ชจ๋ฆฌ ์์ ๋ฐฐ์น | ์ฐ์ | ๋ถ์ฐ์ |
์ถ๊ฐ์ ์ผ๋ก ํ์ํ ๊ณต๊ฐ (Overhead) | - (์์, ๊ตณ์ด ๋ง๋ ๋ค๋ฉด ๋ฐฐ์ด ๊ธธ์ด) | O(N) (์ฃผ์๊ฐ, 32bit 4N๋ฐ์ดํธ, 64bit 8N๋ฐ์ดํธ, N์ ๋น๋กํ๋ ๋งํผ์ ๋ฉ๋ชจ๋ฆฌ) |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
// ์ผ๋งค ์ฐ๊ฒฐ ๋ฆฌ์คํธ
// ๋ฉ๋ชจ๋ฆฌ ๋์ ๋ฌธ์ ๋ก ์ค๋ฌด์์๋ ์ ๋ ์ธ ์ ์๋ ๋ฐฉ์์ด์ง๋ง,
// ์ฝํ
์์๋ ๊ตฌํ ๋์ด๋๊ฐ ์ผ๋ฐ์ ์ธ ๊ตฌํ๋ณด๋ค ๋ฎ์๋ฐ ์๊ฐ๋ณต์ก๋๋ ๋์ผํด์ ์ ์ฉํ ์ ์๋ค
const int MX = 1000005;
int dat[MX], pre[MX], nxt[MX];
int unused = 1; // top?
// ๋ฐฐ์ด ์์๋๋ก ์ ์ฅํ๋ ๊ฒ์ด ์๋, pre nxt์ ์์ index๋ฅผ ์ ์ฅ
// ๋จ, 0๋ฒ์ง๋ ๊ณ ์ ์ ์ธ ๋จ์ ์์์ง๋ก์จ, ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ์ง ์์, ๋งจ ์ฒ์ ์์ ์์ 0๋ฒ์ง ์์๊ฐ ์๋ค๊ณ ์๊ฐ
// ์ด๋ฐ Dummy node๋ฅผ ๋์ง ์์ผ๋ฉด, ์ฝ์
์ญ์ ๋ฑ์ ๊ตฌํํ ๋ ์์๊ฐ ์์ ์๋ ๊ฒฝ์ฐ์ ๋ํ ์์ธ์ฒ๋ฆฌ๋ฅผ ํด์ผ ํ๋ ๋ฒ๊ฑฐ๋ก์์ด
// @ stl list์ ๊ฒฝ์ฐ dummy node๋ ๋งจ ๋ง์ง๋ง์ ์์
fill(pre, pre + MX, -1);
fill(nxt, nxt + MX, -1);
// traverse
// 0๋ฒ์ง์์ ์ถ๋ฐํด nxt๋ฅผ ๋ฐ๋ผ๊ฐ๋
void traverse()
{
int cur = nxt[0];
while(cur != -1)
{
cout << dat[cur] << ' ';
cur = nxt[cur];
}
cout << "\n\n";
}
// insert (int addr์ถ๊ฐํ ์์น์ฃผ์, int num)
// ์๋ก์ด ์์ ์์ฑ
// ์๋ก์ด ์์ pre, nxt ๋์
// ์ฝ์
ํ ์์น์ nxt ๊ฐ๊ณผ ์ฝ์
ํ ์์น์ ๋ค์ ์์์ pre ๊ฐ์ ์ ์์๋ก ๋ณ๊ฒฝ
// unused 1 ์ฆ๊ฐ
void insert(int addr, int num)
{
dat[unused] = num;
pre[unused] = addr;
nxt[unused] = nxt[addr];
if (nxt[addr] != -1) pre[nxt[addr]] = unused;
nxt[addr] = unused;
unused++;
}
// erase
// ์ด์ ์์น์ nxt๋ฅผ ์ญ์ ํ ์์น์ nxt๋ก ๋ณ๊ฒฝ
// ๋ค์ ์์น์ pre๋ฅผ ์ญ์ ํ ์์น์ pre๋ก ๋ณ๊ฒฝ
// ์ผ๋งค ๋ฐฉ๋ฒ์ผ๋ก๋ ์ ๊ฑฐ๋ฅผ ํด๋ ํ๋ก๊ทธ๋จ์ด ์ข
๋ฃ๋ ๋ ๊น์ง ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ ์ ํ๊ณ ์์
// ๊ทธ๋์ ์ค๋ฌด์์๋ ๋ชป์
void erase(int addr)
{
// dummy node์ ์กด์ฌ๋ก ์ธํด ๊ทธ ์ด๋ค ๋
ธ๋๋ฅผ ์ง์ฐ๋๋ผ๋ pre[addr]์ -1์ด ์๋์ด ๋ณด์ฅ๋จ
nxt[pre[addr]] = nxt[addr];
if (nxt[addr] != -1) pre[nxt[addr]] = pre[addr];
// ๋จ์ ๋ฐ์ดํฐ๋ฅผ ์ผ๋ถ๋ฌ ์ง์ธ ํ์๋ ์์
// ์ด์ฐจํผ ์ ๊ทผํ ์ผ๋ ์๊ณ , ์๋ก ๊ฐ์ด ๋ค์ด์ฌ ๋ ๋ฎ์ด์์์ง ๊ฒ์ด๊ธฐ ๋๋ฌธ
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// STL list
#include <bits/stdc++.h>
using namespace std;
// push_back, pop_back, push_front, pop_front๋ ๋ชจ๋ O(1)
int main(void)
{
list<int> L = { 1, 2 }; // 1 2
list<int>::iterator t = L.begin(); // t๋ 1์ ๊ฐ๋ฆฌํค๋ ์ค
// c++ 11 ์ด์ ์ผ๋ auto t = L.begin() ๊ฐ๋ฅ
L.push_front(10); // 10 1 2
cout << *t << '\n'; // t๊ฐ ๊ฐ๋ฆฌํค๋ ๊ฐ = 1์ ์ถ๋ ฅ
L.push_back(5); // 10 1 2 5
L.insert(t, 6); // t๊ฐ ๊ฐ๋ฆฌํค๋ ๊ณณ ์์ 6์ ์ฝ์
, 10 6 1 2 5
t++; // t๋ฅผ 1์นธ ์์ผ๋ก ์ ์ง, ํ์ฌ t๊ฐ ๊ฐ๋ฆฌํค๋ ๊ฐ์ 2
t = L.erase(t); // t๊ฐ ๊ฐ๋ฆฌํค๋ ๊ฐ์ ์ ๊ฑฐ, ๊ทธ ๋ค์ ์์์ธ 5์ ์์น๋ฅผ ๋ฐํ
// 10 6 1 5, t๊ฐ ๊ฐ๋ฆฌํค๋ ๊ฐ์ 5
cout << *t << '\n'; // 5
for(auto i : L) cout << i << ' '; // C++ 11 ์ด์
cout << '\n';
for(list<int>::iterator it = L.begin(); it != L.end(); it++)
cout << *it << ' ';
}// remove unique merge reverse sort splice
// []๋ฅผ ์ง์ํ์ง ์์, ๋ฐ๋ผ์ ์์ ์ ๊ทผ ๋ฐ๋ณต์๋ฅผ ํ์๋ก ํ๋ binary_search ์๊ณ ๋ฆฌ๋ฌ ์ ์ฉํ ์ ์๋ค
์ค๊ฐ์ ๋ง๋๋ ๋ ์ฐ๊ฒฐ ๋ฆฌ์คํธ์ ์์์ ๋ค์ด ์ฃผ์ด์ก์ ๋ ๋ง๋๋ ์ง์ ์ ๊ตฌํ๋ ๋ฐฉ๋ฒ?
๋ ๋ค ๋๊น์ง ์งํ์ํจ ํ์ ๊ทธ ๊ธธ์ด๋ฅผ ๊ธฐ๋ก
๋ค์ ์์์ ๋ค๋ก ๋์์์ ์งง์ ์ชฝ์ ๊ธธ์ด ์ฐจ์ด๋งํผ ๋จผ์ ์งํ
์ดํ ๋์์ ํ๋์ฉ ์ ์งํด๋๊ฐ๋ฉฐ ๋ง๋๋ ์ง์ ์ฐพ๊ธฐ
๊ณต๊ฐ ๋ณต์ก๋ O(1), ์๊ฐ ๋ณต์ก๋ O(A + B)
์ฃผ์ด์ง ์ฐ๊ฒฐ ๋ฆฌ์คํธ ์์ ์ฌ์ดํด์ด ์๋์ง ํ๋จํ๋ผ
Floydโs cycle-finding algorithm, ๊ณต๊ฐ ๋ณต์ก๋ O(1), ์๊ฐ ๋ณต์ก๋ O(N)
- ์ด์ ์ฒด์ ์์ ๋์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๊ด๋ฆฌํ ๋
- ํฌ์ ํ๋ ฌ Sparse Matrix์ ํํํ ๋
- ๋ฑ์ด๋ ์คํ, ํ์ ๊ฐ์ ๋ค๋ฅธ ์๋ฃ๊ตฌ์กฐ๋ฅผ ํํํ ๋ ๊ธฐ์ด ์๋ฃ ๊ตฌ์กฐ๋ก
- ํ ์คํธ ์๋ํฐ๋ ๋ด๋ถ์ ์ผ๋ก ์ปจํ ์ธ ๋ฅผ ์ ์ฅํ ๋ ์ฐ๊ฒฐ๋ฆฌ์คํธ๋ฅผ ์ฌ์ฉ. ํ ์คํธ ํ์ผ์ ์ค๊ฐ์์ ๋ฌธ์๊ฐ ์ ๋ ฅ๋ ์ ์๊ธฐ ๋๋ฌธ