๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
โœจ Algorithm/๐Ÿ•‍๐Ÿฆบ ๋ฐ”ํ‚น๋… ๊ฐœ๋…

[0x04] ์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ

by nitronium102 2023. 6. 20.

์ •์˜์™€ ์„ฑ์งˆ

์„ฑ์งˆ

  1. ์ž„์˜์˜ ์œ„์น˜์— ์žˆ๋Š” ์›์†Œ๋ฅผ ํ™•์ธ/๋ณ€๊ฒฝ : O(N) (๋ถˆ์—ฐ์†์ด๊ธฐ ๋•Œ๋ฌธ์— ๊ทธ ์›์†Œ๊นŒ์ง€ ์ฐพ์•„๊ฐ€์•ผ ํ•จ)
  2. ์ž„์˜์˜ ์œ„์น˜์— ์›์†Œ๋ฅผ ์ถ”๊ฐ€/์ œ๊ฑฐ : O(1)
  3. ์›์†Œ๋“ค์ด ๋ฉ”๋ชจ๋ฆฌ ์ƒ์— ์—ฐ๊ฒฐ๋˜์–ด ์žˆ์ง€ ์•Š์•„ cache hit rate๊ฐ€ ๋‚ฎ์ง€๋งŒ ํ• ๋‹น์ด ๋‹ค์†Œ ์‰ฌ์›€

์ข…๋ฅ˜

  1. ๋‹จ์ผ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ single linked list
  2. ์ด์ค‘ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ doubly linked list
  3. ์›ํ˜• ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ 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)

๋Œ“๊ธ€