12. DFS BFS - bloodfinger8/AlgorithmStudy GitHub Wiki
๊น์ด ์ฐ์ ํ์(Deep-first search)๋ ํ์ํธ๋ฆฌ์ ์ต๊ทผ์ ์ฒจ๊ฐ๋ ๋
ธ๋๋ฅผ ์ ํํ๊ณ , ์ด ๋
ธ๋์ ์ ์ฉ ๊ฐ๋ฅํ ๋์์ ์ค ํ๋๋ฅผ ์ ์ฉํ์ฌ ํธ๋ฆฌ์ ๋ค์ ์์ค(level)์ ํ ๊ฐ์ ์์๋
ธ๋๋ฅผ ์ฒจ๊ฐํ๋ฉฐ, ์ฒจ๊ฐ๋ ์์ ๋
ธ๋๊ฐ ๋ชฉํ๋
ธ๋์ผ ๋๊น์ง ์์ ์์ ๋
ธ๋์ ์ฒจ๊ฐ ๊ณผ์ ์ ๋ฐ๋ณตํด ๊ฐ๋ ๋ฐฉ์์ด๋ค.
- ๋จ์ง ํ ๊ฒฝ๋ก์์ ๋ ธ๋๋ค๋ง์ ๊ธฐ์ตํ๋ฉด ๋๋ฏ๋ก ์ ์ฅ๊ณต๊ฐ์ ์์๊ฐ ๋น๊ต์ ์ ๋ค.
- ๋ชฉํ๋ ธ๋๊ฐ ๊น์ ๋จ๊ณ์ ์์ ๊ฒฝ์ฐ ํด๋ฅผ ๋นจ๋ฆฌ ๊ตฌํ ์ ์๋ค.
- ํด๊ฐ ์๋ ๊ฒฝ๋ก์ ๊น์ด ๋น ์ง ๊ฐ๋ฅ์ฑ์ด ์๋ค. ๋ฐ๋ผ์ ์ค์ ์ ๊ฒฝ์ฐ ๋ฏธ๋ฆฌ ์ง์ ํ ์์์ ๊น์ด๊น์ง๋ง ํ์ํ๊ณ ๋ชฉํ๋ ธ๋๋ฅผ ๋ฐ๊ฒฌํ์ง ๋ชปํ๋ฉด ๋ค์์ ๊ฒฝ๋ก๋ฅผ ๋ฐ๋ผ ํ์ํ๋ ๋ฐฉ๋ฒ์ด ์ ์ฉํ ์ ์๋ค.
- ์ป์ด์ง ํด๊ฐ ์ต๋จ ๊ฒฝ๋ก๊ฐ ๋๋ค๋ ๋ณด์ฅ์ด ์๋ค. ์ด๋ ๋ชฉํ์ ์ด๋ฅด๋ ๊ฒฝ๋ก๊ฐ ๋ค์์ธ ๋ฌธ์ ์ ๋ํด ๊น์ด์ฐ์ ํ์์ ํด์ ๋ค๋ค๋ฅด๋ฉด ํ์์ ๋๋ด๋ฒ๋ฆฌ๋ฏ๋ก, ์ด๋ ์ป์ด์ง ํด๋ ์ต์ ์ด ์๋ ์ ์๋ค๋ ์๋ฏธ์ด๋ค.
class Graph {
private int V; // ๋
ธ๋์ ๊ฐ์
private LinkedList<Integer> adj[]; // ์ธ์ ๋ฆฌ์คํธ
/** ์์ฑ์ */
Graph(int v) {
V = v;
adj = new LinkedList[v];
for (int i=0; i<v; ++i) // ์ธ์ ๋ฆฌ์คํธ ์ด๊ธฐํ
adj[i] = new LinkedList();
}
/** ๋
ธ๋๋ฅผ ์ฐ๊ฒฐ v->w */
void addEdge(int v, int w) { adj[v].add(w); }
/** DFS์ ์ํด ์ฌ์ฉ๋๋ ํจ์ */
void DFSUtil(int v, boolean visited[]) {
// ํ์ฌ ๋
ธ๋๋ฅผ ๋ฐฉ๋ฌธํ ๊ฒ์ผ๋ก ํ์ํ๊ณ ๊ฐ์ ์ถ๋ ฅ
visited[v] = true;
System.out.print(v + " ");
// ๋ฐฉ๋ฌธํ ๋
ธ๋์ ์ธ์ ํ ๋ชจ๋ ๋
ธ๋๋ฅผ ๊ฐ์ ธ์จ๋ค.
Iterator<Integer> i = adj[v].listIterator();
while (i.hasNext()) {
int n = i.next();
// ๋ฐฉ๋ฌธํ์ง ์์ ๋
ธ๋๋ฉด ํด๋น ๋
ธ๋๋ฅผ ์์ ๋
ธ๋๋ก ๋ค์ DFSUtil ํธ์ถ
if (!visited[n])
DFSUtil(n, visited); // ์ํ ํธ์ถ
}
}
/** ์ฃผ์ด์ง ๋
ธ๋๋ฅผ ์์ ๋
ธ๋๋ก DFS ํ์ */
void DFS(int v) {
// ๋
ธ๋์ ๋ฐฉ๋ฌธ ์ฌ๋ถ ํ๋จ (์ด๊น๊ฐ: false)
boolean visited[] = new boolean[V];
// v๋ฅผ ์์ ๋
ธ๋๋ก DFSUtil ์ํ ํธ์ถ
DFSUtil(v, visited);
}
/** DFS ํ์ */
void DFS() {
// ๋
ธ๋์ ๋ฐฉ๋ฌธ ์ฌ๋ถ ํ๋จ (์ด๊ธฐ๊ฐ: false)
boolean visited[] = new boolean[V];
// ๋น์ฐ๊ฒฐํ ๊ทธ๋ํ์ ๊ฒฝ์ฐ, ๋ชจ๋ ์ ์ ์ ํ๋์ฉ ๋ฐฉ๋ฌธ
for (int i=0; i<V; ++i) {
if (visited[i] == false)
DFSUtil(i, visited);
}
}
}
๋๋น ์ฐ์ ํ์(Breadth-first search)๋ ์์ ์ ์ ์ ๋ฐฉ๋ฌธํ ํ ์์ ์ ์ ์ ์ธ์ ํ ๋ชจ๋ ์ ์ ๋ค์ ์ฐ์ ๋ฐฉ๋ฌธํ๋ ๋ฐฉ๋ฒ์ด๋ค. ๋ ์ด์ ๋ฐฉ๋ฌธํ์ง ์์ ์ ์ ์ด ์์ ๋๊น์ง ๋ฐฉ๋ฌธํ์ง ์์ ๋ชจ๋ ์ ์ ๋ค์ ๋ํด์๋ ๋๋น ์ฐ์ ๊ฒ์์ ์ ์ฉํ๋ค.
- ์ถ๋ฐ๋ ธ๋์์ ๋ชฉํ๋ ธ๋๊น์ง์ ์ต๋จ ๊ธธ์ด ๊ฒฝ๋ก๋ฅผ ๋ณด์ฅํ๋ค.
- ๊ฒฝ๋ก๊ฐ ๋งค์ฐ ๊ธธ ๊ฒฝ์ฐ์๋ ํ์ ๊ฐ์ง๊ฐ ๊ธ๊ฒฉํ ์ฆ๊ฐํจ์ ๋ฐ๋ผ ๋ณด๋ค ๋ง์ ๊ธฐ์ต ๊ณต๊ฐ์ ํ์๋ก ํ๊ฒ ๋๋ค.
- ํด๊ฐ ์กด์ฌํ์ง ์๋๋ค๋ฉด ์ ํ ๊ทธ๋ํ(finite graph)์ ๊ฒฝ์ฐ์๋ ๋ชจ๋ ๊ทธ๋ํ๋ฅผ ํ์ํ ํ์ ์คํจ๋ก ๋๋๋ค.
- ๋ฌดํ ๊ทธ๋ํ(infinite graph)์ ๊ฒฝ์ฐ์๋ ๊ฒฐ์ฝ ํด๋ฅผ ์ฐพ์ง๋ ๋ชปํ๊ณ , ๋๋ด์ง๋ ๋ชปํ๋ค.
Class Graph {
private int V; // ๋
ธ๋์ ๊ฐ์
private LinkedList<Integer> adj[]; // ์ธ์ ๋ฆฌ์คํธ
/** ์์ฑ์ */
Graph(int v) {
V = v;
adj = new LinkedList[v];
for (int i=0; i<v; ++i) // ์ธ์ ๋ฆฌ์คํธ ์ด๊ธฐํ
adj[i] = new LinkedList();
}
/** ๋
ธ๋๋ฅผ ์ฐ๊ฒฐ v->w */
void addEdge(int v, int w) { adj[v].add(w); }
/** s๋ฅผ ์์ ๋
ธ๋์ผ๋ก ํ BFS๋ก ํ์ํ๋ฉด์ ํ์ํ ๋
ธ๋๋ค์ ์ถ๋ ฅ */
void BFS(int s) {
// ๋
ธ๋์ ๋ฐฉ๋ฌธ ์ฌ๋ถ ํ๋จ (์ด๊น๊ฐ: false)
boolean visited[] = new boolean[V];
// BFS ๊ตฌํ์ ์ํ ํ(Queue) ์์ฑ
LinkedList<Integer> queue = new LinkedList<Integer>();
// ํ์ฌ ๋
ธ๋๋ฅผ ๋ฐฉ๋ฌธํ ๊ฒ์ผ๋ก ํ์ํ๊ณ ํ์ ์ฝ์
(enqueue)
visited[s] = true;
queue.add(s);
// ํ(Queue)๊ฐ ๋น ๋๊น์ง ๋ฐ๋ณต
while (queue.size() != 0) {
// ๋ฐฉ๋ฌธํ ๋
ธ๋๋ฅผ ํ์์ ์ถ์ถ(dequeue)ํ๊ณ ๊ฐ์ ์ถ๋ ฅ
s = queue.poll();
System.out.print(s + " ");
// ๋ฐฉ๋ฌธํ ๋
ธ๋์ ์ธ์ ํ ๋ชจ๋ ๋
ธ๋๋ฅผ ๊ฐ์ ธ์จ๋ค.
Iterator<Integer> i = adj[s].listIterator();
while (i.hasNext()) {
int n = i.next();
// ๋ฐฉ๋ฌธํ์ง ์์ ๋
ธ๋๋ฉด ๋ฐฉ๋ฌธํ ๊ฒ์ผ๋ก ํ์ํ๊ณ ํ์ ์ฝ์
(enqueue)
if (!visited[n]) {
visited[n] = true;
queue.add(n);
}
}
}
}
}