์ ์์ ์ฑ์ง
์ฑ์ง
- ์์์ ์์น์ ์๋ ์์๋ฅผ ํ์ธ/๋ณ๊ฒฝ : O(N) (๋ถ์ฐ์์ด๊ธฐ ๋๋ฌธ์ ๊ทธ ์์๊น์ง ์ฐพ์๊ฐ์ผ ํจ)
- ์์์ ์์น์ ์์๋ฅผ ์ถ๊ฐ/์ ๊ฑฐ : O(1)
- ์์๋ค์ด ๋ฉ๋ชจ๋ฆฌ ์์ ์ฐ๊ฒฐ๋์ด ์์ง ์์ cache hit rate๊ฐ ๋ฎ์ง๋ง ํ ๋น์ด ๋ค์ ์ฌ์
์ข ๋ฅ
- ๋จ์ผ ์ฐ๊ฒฐ ๋ฆฌ์คํธ single linked list
- ์ด์ค ์ฐ๊ฒฐ ๋ฆฌ์คํธ doubly linked list
- ์ํ ์ฐ๊ฒฐ ๋ฆฌ์คํธ circular linked list
๋ฐฐ์ด vs ์ฐ๊ฒฐ ๋ฆฌ์คํธ
- overhead : ์, ๋ค ์์์ ์ฃผ์๊ฐ์ ๊ฐ์ง๊ณ ์์ด์ผ ํ๋ค (2^n byte์ด๋ฉด n๋งํผ ์ถ๊ฐ๋ก ํ์)
๊ตฌํ
struct Node {
struct Node *prev, *next;
int data;
}
์ผ๋งค ์ฐ๊ฒฐ๋ฆฌ์คํธ
const int MAX = 1000005;
int data[MAX], pre[MAX], next[MAX]; // pre next : ์ด์ /๋ค์ ์์์ ์ฃผ์
int unused = -1; // ์๋ก์ด ์์๊ฐ ๋ค์ด๊ฐ ์ ์๋ ์ธ๋ฑ์ค, ์์ ์์ ์ 1์ฉ ์ฆ๊ฐ
// ๊ธธ์ด๊ฐ ํ์ํ๋ฉด len ๋ณ์๋ฅผ ๋๋ฉด ๋๋ค
// 0๋ฒ์งธ๋ ์ฐ๊ฒฐ๋ฆฌ์คํธ์ ์์, ์ฆ dummy node (์ฝ์
, ์ญ์ ์ ์์ธ์ฒ๋ฆฌ ์ค์ด๊ธฐ ์ํด)
fill(pre, pre+MAX, -1);
fill(next, next+MAX, -1);
traverse ํจ์
void traverse() {
int cur = next[0];
while(cur != -1){
cout << data[cur] << ' ';
cur = next[cur];
}
cout << "\\n\\n";
}
insert์ erase ํจ์
void insert(int addr, int num) { // ์ธ์ : ์ฝ์
ํ ์์น, ์ฝ์
ํ ๊ฐ
// 1. ์๋ก์ด ์์ ์์ฑ
data[unused] = num;
pre[unused] = addr;
next[unused] = next[addr]
// 2. ์ฝ์
ํ ์์น์ next, ์ฝ์
ํ ์์น์ ๋ค์ ์์์ pre ๊ฐ ๋ณ๊ฒฝ
if (next[addr] != -1) pre[next[addr]] = unused; // ๋งจ ๋ง์ง๋ง์ด ์๋ ๊ฒฝ์ฐ
next[addr] = unused;
// 3. unused ์ฆ๊ฐ
unused++;
}
void erase(int addr) {
// 1. ์ด์ ์์น์ next๋ฅผ ์ญ์ ํ ์์น์ next๋ก ๋ณ๊ฒฝ (dummy node๋ก ์ธํด -1 ์๋ ๋ณด์ฅ)
next[prev[addr]] = next[addr];
// 2. ๋ค์ ์์น์ pre๋ฅผ ์ญ์ ํ ์์น์ pre๋ก ๋ณ๊ฒฝ
if (next[addr] != -1) prev[next[addr]] = prev[addr];
}
STL list
- insert (idx, val) : idx ์์ val์ ์ฝ์
- erase (idx) : idx๋ฅผ ์ ๊ฑฐํ๊ณ ๊ทธ ๋ค์ ์์น์ val์ ๋ฐํ
#include <bits/stdc++.h>
using namespace std;
int main(void) {
list<int> L = {1,2}; // 1 2
list<int>::iterator t = L.begin(); // t๋ 1์ ๊ฐ๋ฆฌํค๋ ์ค
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 << ' ';
cout << '\\n';
for(list<int>::iterator it = L.begin(); it != L.end(); it++)
cout << *it << ' ';
}
๋ฉด์ ๋ฌธ์
1. ์ํ ์ฐ๊ฒฐ ๋ฆฌ์คํธ ๋ด์ ์์์ ๋ ธ๋ ํ๋๊ฐ ์ฃผ์ด์ก์ ๋ ํด๋น List์ ๊ธธ์ด๋ฅผ ํจ์จ์ ์ผ๋ก ๊ตฌํ๋ ๋ฐฉ๋ฒ?
→ ๋์ผํ ๋ ธ๋๊ฐ ๋์ฌ ๋๊น์ง ๊ณ์ ๋ค์ ๋ ธ๋๋ก ๊ฐ๋ฉด ๋๋ค
→ ๊ณต๊ฐ๋ณต์ก๋ O(1), ์๊ฐ๋ณต์ก๋ O(N)
2. ์ค๊ฐ์ ๋ง๋๋ ๋ ์ฐ๊ฒฐ ๋ฆฌ์คํธ์ ์์์ ๋ค์ด ์ฃผ์ด์ก์ ๋ ๋ง๋๋ ์ง์ ์ ๊ตฌํ๋ ๋ฐฉ๋ฒ?→ ๊ทธ ํ ๋ค์ ๋ ์์์ ์ผ๋ก ๋์์์ ๋ ๊ธด ์ชฝ์ ๋์ ์ฐจ์ด๋งํผ ์์ผ๋ก ๋จผ์ ์ด๋⇒ ๊ณต๊ฐ๋ณต์ก๋ O(1), ์๊ฐ๋ณต์ก๋ O(A+B)
→ ๋ ์ง์ ์ด ๋ง๋ ๋๊น์ง ๋ ์์์ ์ ๋์์ ํ ์นธ์ฉ ์ ์ง
→ ์ผ๋จ ๋ ์์์ ๊ฐ๊ฐ์ ๋ํด ๋๊น์ง ์งํ์์ผ์ ๊ฐ๊ฐ์ ๊ธธ์ด๋ฅผ ๊ตฌํจ
3. ์ฃผ์ด์ง ์ฐ๊ฒฐ ๋ฆฌ์คํธ ์์ ์ฌ์ดํด์ด ์๋์ง ํ๋จ?
→ Floyd’s Cycle-finding algorithm
ํ ์นธ์ฉ ๊ฐ๋ ์ปค์์ ๋ ์นธ์ฉ ๊ฐ๋ ์ปค์๋ฅผ ๋์ผํ ์์์ ์์ ์ถ๋ฐ์ํค๋ฉด
์ฌ์ดํด์ด ์์ ๊ฒฝ์ฐ ๋ ์ปค์๋ ๋ฌด์กฐ๊ฑด ๋ง๋จ
์์ ๊ฒฝ์ฐ ๋ ์ปค์๋ ์ฐ๊ฒฐ ๋ฆฌ์คํธ์ ๋์ ๋๋ฌ
⇒ ๊ณต๊ฐ๋ณต์ก๋ O(1), ์๊ฐ๋ณต์ก๋ O(N)
'โจ Algorithm > ๐โ๐ฆบ ๋ฐํน๋ ๊ฐ๋ ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[0x06] ํ (0) | 2023.06.20 |
---|---|
[0x05] ์คํ (0) | 2023.06.20 |
[0x03] ๋ฐฐ์ด (0) | 2023.06.20 |
[0x02] ๊ธฐ์ด ์ฝ๋ ์์ฑ ์๋ น 2 (0) | 2023.06.20 |
[0x01] ๊ธฐ์ด ์ฝ๋ ์์ฑ ์๋ น 1 (0) | 2023.06.20 |
๋๊ธ