Data Structures & Algorithms with Javascript : Binary Trees and Binary Search Trees
2024.07.24 - [๐ค data structures & algorithms] - Data Structures & Algorithms with Javascript : Sets Data Structures & Algorithms with Javascript : Sets[์ด์ ๊ธ]2024.07.23 - [๐ค data structures & algorithms] - Data Structures & Algorithms with Java
pyotato-dev.tistory.com
์ค๋์ ๊ทธ๋ํ๋ก ๋คํธ์ํฌ๊ฐ ๋ชจ๋ธ๋ง ๋๋ ๋ฐฉ์, ๊ทธ๋ํ๊ฐ ๋ฌด์์ธ์ง, ์๋ฐ์คํฌ๋ฆฝํธ๋ก ๊ตฌํ ๋ฑ์ ๋ํด ์ดํด๋ณด์.
โผ ์์ ๋ ์ฑ ์ ๊ตฌํ์ ์ฐธ๊ณ ํ์ฌ ํด๋์ค๋ก ์ฌ๊ตฌ์ฑํ์ต๋๋ค!!
๐ธ๏ธ ๊ทธ๋ํ๋?
๊ทธ๋ํ๋ vertice(vertex์ ๋ณต์ํ)์ edge๋ก ๊ตฌ์ฑ๋๋ค.
๊ทธ๋ํ์ ๊ฐ๋ ์ ๊ฐ๋จ๊ตฌ ์ง๋์ ๋์ ํด๋ณด์๋ฉด vertice๋ ๊ฐ๋จ์ญ, ์ญ์ผ์ญ, ์ผ์ฑ์ญ ๋ฑ๋ฑ์ ์ญ์ด๊ณ ,
๊ฐ ์ญ์ ์ฐ๊ฒฐํ๊ณ ์๋ 2ํธ์ ์งํ์ฒ ์ด edge์ ํด๋น๋๋ค.
๊ฐ๋จ์ญ(v1)์์ ์ผ์ฑ์ญ(v2)์ผ๋ก ๊ฐ๋ ์งํ์ฒ ๋ ธ์ ๋ ์๊ฒ ์ง๋ง ๋ฒ์ค๋ฅผ ํ๊ณ ๊ฐ ์๋ ์๊ณ , ๊ฑธ์ด๊ฐ๋ ๊ธธ๋ ์์ ์๋ ์๋ค.
๊ฐ๋ ๋ฐฉ๋ฒ์ ๋ฐ๋ผ ๋น์ฉ์ด๋ ์๊ฐ์ด ๋ฌ๋ผ์ง ์ ์๋๋ฐ, ๊ทธ๋ํ์์๋ ์ด ๋น์ฉ์ weight (cost) ๋ผ๊ณ ํ๋ค.
๊ฐ๋จ์ญ(v1)์์ ์ผ์ฑ์ญ(v2)์ผ๋ก ์ด์ด์ง๋ edge๋ฅผ pair(v1, v2)๋ก ์ ์ํ ์ ์๋ค.
vertice๋ค์ ์ฐ๊ฒฐํ๋ edge๋ค์ path๋ผ๊ณ ํ๋๋ฐ, ์๊ธฐ ์์ ์ vertex๋ก ์ฐ๊ฒฐ๋ path๋ loop๋ผ๊ณ ํ๋ค.
ํ๋์ vertex์์ ๋ค๋ฅธ vertex๊น์ง๋ฅผ path์ ๊ธธ์ด(length)๋ผ๊ณ ํ๊ณ , loop์ path ๊ธธ์ด๋ 0์ด๋ค.
์๋์ ์ง๋๋ ์ถ๋ฐ ์ง์ ๊ณผ ๋์ฐฉ์ง์ ์ด ์๋ค. ์ด๋ ๊ฒ ๋ฐฉํฅ์ด ์๋ ๊ทธ๋ํ๋ directed graph (digraph)๋ผ๊ณ ํ๋ค.
๋ฐ๋ฉด์ ๋ฐฉํฅ์ด ์๋ ๊ทธ๋ํ๋ unordred graph (graph)๋ผ๊ณ ํ๋ค.
๋ vertice ์ฌ์ด์ path๊ฐ ์๋ค๋ฉด strongly connected๋ผ๊ณ ํํํ๋ค.
๐บ๏ธ ๊ทธ๋ํ ๊ตฌํ
์ธ๋ป๋ณด๋ฉด ๊ทธ๋ํ ๊ตฌ์กฐ๊ฐ ํธ๋ฆฌ๋ ์ด์งํธ๋ฆฌ์ ๋น์ทํด ๋ณด์ด๊ธฐ ๋๋ฌธ์ ๊ฐ vertex๋ฅผ ๋ํ๋ด๊ธฐ ์ํด Node ํด๋์ค๋ก ๋ํ๋ด๋ ค๊ณ ํ ์๋ ์๋ค. ํ์ง๋ง Node ํด๋์ค์ ๊ฐ์ ๊ฐ์ฒด ๊ธฐ๋ฐ์ ์ ๊ทผ์ ๊ทธ๋ํ์ ํฌ๊ธฐ๊ฐ ์ปค์ง์ ๋ฐ๋ผ ๋ถ์ ํฉํ ์ ์๋ค. ๊ทธ๋ฆฌ๊ณ ์ด์งํธ๋ฆฌ๋ ์์ ๋ ธ๋์ ๊ฐ์๊ฐ 2๊ฐ ์ดํ๋ก ์ ํ๋์๊ธฐ ๋๋ฌธ์ ๋ ธ๋ ๊ฐ์ ์ฐ๊ฒฐ์ด ๋ฌดํํ ์ ์๋ ๊ทธ๋ํ๋ฅผ ํํํ๊ธฐ์๋ ์ด๋ ค์์ด ์๋ค.
๊ทธ๋ผ ์ด๋ค ์๋ฃ ๊ตฌ์กฐ๋ก vertice์ edge๋ฅผ ํํํ ์ ์์๊น?
Vertex ๊ตฌํ
Graph ํด๋์ค๋ฅผ ๋ง๋ค๊ธฐ ์ํด ๊ทธ๋ํ๋ฅผ ๊ตฌ์ฑํ Vertex๊ฐ ํ์ํ๋ค.
์ด์ง ํ์ ํธ๋ฆฌ์ linked list์์ ์ดํด๋ดค๋ ๊ฒ์ฒ๋ผ Node ํด๋์ค๋ Vertex์ ๋น์ทํ ๊ธฐ๋ฅ์ ์ํํด์ผํ๋ค.
Vertex๊ฐ ์ง๋ ์ผ ํ ์ ๋ณด๋ ๋ค์๊ณผ ๊ฐ๋ค
- label : vertex์ ๊ฐ
- wasVisited : vertex ๋ฐฉ๋ฌธ ์ฌ๋ถ
class Vertex{
constructor(label){
this.label = label;
}
}
Edge ๊ตฌํ
์ธ์ ๋ฆฌ์คํธ (adjacency list ๋๋ array of adjacency lists)
๋ ๊ฐ์ ๋ฐฐ์ด์ ํ์ฉํ๋ค. ๊ฐ ๋ฐฐ์ด์ ์ธ๋ฑ์ค๊ฐ vertice๋ฅผ ๋ํ๋ด๊ณ , ๊ฐ ๋ฐฐ์ด์ ๊ฐ์ ๊ทธ vertice๊ฐ ์ฐ๊ฒฐ๋ vetice๋ฅผ ๋ํ๋ธ๋ค.
์๋ฅผ ๋ค๋ฉด ๋ค์๊ณผ ๊ฐ์ ๊ทธ๋ํ๊ฐ ์๋ค๊ณ ํ์. vertice 2๋ ๋๋จธ์ง 0,1,3,4์ ์ฐ๊ฒฐ๋ edge๋ค์ด ์๋ค.
์ธ์ ๋ฆฌ์คํธ๋ฅผ ํ์ฉํด์ ๋ค์๊ณผ ๊ฐ์ด ์ฐ๊ฒฐ ๊ด๊ณ๋ฅผ ํํํ ์ ์๋ค.
vertex ์ธ๋ฑ์ค 0์๋ vertex ์ธ๋ฑ์ค 2๊ฐ, ์ธ๋ฑ์ค 1์๋ 2๊ฐ ์ธ๋ฑ์ค 2๋ 0,1,3,4๊ฐ, ์ธ๋ฑ์ค 3์ ์ธ๋ฑ์ค 2๊ฐ, ๊ทธ๋ฆฌ๊ณ ์ธ๋ฑ์ค 4๋ 2๋ฅผ ๋ฐฐ์ด ์์๋ก ์ง๋ ์ ์๋ค.
์ธ์ ํ๋ ฌ (adjacency matrix)
์ด์ฐจ์ ๋ฐฐ์ด๋ก ๋ vertice ์ฌ์ด์ edge๊ฐ ์กด์ฌํ๋์ง ๋ํ๋ด๋ ๋ฐฉ์์ผ๋ก๋ ๋ํ๋ผ ์ ์๋ค.
vertex ์ฌ์ด์ edge๊ฐ ์กด์ฌํ๋ฉด true(1), ์๋๋ฉด false(0)
0, 1, 2, 3, 4
0 [0, 0, 1, 0, 0]
1 [0, 0, 1, 0, 0]
2 [1, 1, 0, 1, 1]
3 [0, 0, 1, 0, 0]
4 [0, 0, 1, 0, 0]
๊ทธ๋ํ ๊ตฌํ
์ฐ๋ฆฌ๋ ์ธ์ ๋ฆฌ์คํธ๋ก ๊ทธ๋ํ๋ฅผ ๊ตฌํํด๋ณด์.
class Graph {
constructor(v){
this.vertices = v;
this.edges = 0;
this.adj = []; // ์ธ์ ๋ฆฌ์คํธ๋ก ๊ตฌํ
for(let i=0; i<this.vertices;++i){
this.adj[i] = [];
}
}
// ์ถ๋ ฅ ํฌํผ ํจ์
print(item){
console.log(item);
}
// edge ์ถ๊ธฐ
addEdge(v,w){
this.adj[v].push(w);
this.adj[w].push(v);
this.edges++;
}
// ๊ทธ๋ํ ๊ทธ๋ฆฌ๊ธฐ
showGraph(){
for(let i=0; i< this.vertices; ++i){
this.print(`${i} -> ${this.adj[i].join(', ')}`);
}
}
}
const graph = new Graph(5);
graph.addEdge(0,1);
graph.addEdge(0,2);
graph.addEdge(1,3);
graph.addEdge(2,4);
graph.showGraph();
/**
0 -> 1, 2
1 -> 0, 3
2 -> 0, 4
3 -> 1
4 -> 2
*/
๊ทธ๋ํ ํ์
๊ทธ๋ํ ํ์ ์๊ณ ๋ฆฌ์ฆ์๋ ๋ ๊ฐ์ง๊ฐ ์๋ค : DFS(depth-first-search)์ BFS (breadth-first search)
DFS (๊น์ด ์ฐ์ ํ์)
dfs๋ ์์ํ๋ vertex์์ ๋ง์ง๋ง vertex์ ๋๋ฌํ ๋๊น์ง ํ์ํ๊ณ ,
๋ vertex์์ ์ญ์ผ๋ก ๊ฑฐ์ฌ๋ฌ (backtrack) ์ฌ๋ผ์์ ๋ ์ด์ ๋ฐฉ๋ฌธํ์ง ์์ vertex๊ฐ ์์ ๋๊น์ง ๋ค์ path์ ํ์ํ๋ค.
dfs ์๊ณ ๋ฆฌ์ฆ ๊ตฌํ ๋ก์ง์ ๊ฐ๋จํ ํธ์ด๋ค. ์์ง ๋ฐฉ๋ฌธํ์ง ์์ vertex๋ค์ ๋ฐฉ๋ฌธํ๊ณ ๋ฐฉ๋ฌธ์ฌ๋ถ๋ฅผ ๋งํฌํ๋ฉด ๋๋ค.
๋ฐฉ๋ฌธํ์ง ์์ vertex๊ฐ ์์ ๋๊น์ง ์ฌ๊ท์ ์ผ๋ก ํ์์ ํ๋ฉด ๋๋ค.
๊ตฌํ
class Graph {
constructor(v){
this.vertices = v;
this.edges = 0;
this.adj = [];
for(let i=0; i<this.vertices;++i){
this.adj[i] = [];
}
/////////////////////////// ๐์์ ///////////////////////////
this.visited = [];
for(let i=0; i<this.vertices;++i){
this.visited[i] = false;
}
/////////////////////////// ๐์์ ///////////////////////////
}
// ์ถ๋ ฅ ํฌํผ ํจ์
print(item){
console.log(item);
}
// edge ์ถ๊ธฐ
addEdge(v,w){
this.adj[v].push(w);
this.adj[w].push(v);
this.edges++;
}
// ๊ทธ๋ํ ๊ทธ๋ฆฌ๊ธฐ
showGraph(){
for(let i=0; i< this.vertices; ++i){
this.print(`${i} -> ${this.adj[i].join(', ')}`);
}
}
/////////////////////////// ๐์ถ๊ฐ ///////////////////////////
// dfs
dfs(v){
this.visited[v] = true;
if(this.adj[v] != undefined){
this.print(`visited vertex: ${v}`);
}
this.adj[v].forEach((w)=>{
if(!this.visited[w]){
this.dfs(w);
}
})
}
/////////////////////////// ๐์ถ๊ฐ ///////////////////////////
}
const graph = new Graph(5);
graph.addEdge(0,1);
graph.addEdge(0,2);
graph.addEdge(1,3);
graph.addEdge(2,4);
graph.showGraph();
graph.dfs(0);
/**
0 -> 1, 2
1 -> 0, 3
2 -> 0, 4
3 -> 1
4 -> 2
visited vertex: 0
visited vertex: 1
visited vertex: 3
visited vertex: 2
visited vertex: 4
*/
BFS (๋๋น ์ฐ์ ํ์)
bfs๋ ์ฒซ vertex์์ ์์ํด์ ๊ฐ๋ฅํ ๊ฐ์ฅ ๊ฐ๊น์ด vertex๋ฅผ ์ฐพ์ ๋ฐฉ๋ฌธํ๋ค.
ํ๋์ path์ ๋ฐ๋ผ ๋ง์ง๋ง vertex์ ๋ฐฉ๋ฌธํ๋ ค๋ dfs์๋ ๋ฌ๋ฆฌ bfs๋ layer ๋จ์๋ก ๋จผ์ ๋ฐฉ๋ฌธํ๋ค.
์์ ๊ทธ๋ฆผ์์ k, h, e, b๋ ๊ฐ์ layer์, c, f, i, l๋ ๊ฐ์ layer๋ค. bfs๋ ์ฒซ vertex์ธ a๋ถํฐ ์์ํด์ ๊ฐ๊น์ด layer๋ค์ vertex๋ค์ ๋ฐฉ๋ฌธํ๋ค. bfs๋ vertice ๋ฐฉ๋ฌธ์ ํํํ๊ธฐ ์ํด queue๋ฅผ ์ถ์ํํ ์๊ณ ๋ฆฌ์ฆ์ ํ์ฉํ๋ค.
์๊ณ ๋ฆฌ์ฆ ๋ก์ง์ ๋ค์๊ณผ ๊ฐ๋ค.
- ํ์ฌ vertex์ ๊ฐ์ฅ ๊ฐ๊น์ด ๋ฐฉ๋ฌธํ์ง ์์ vertex๋ฅผ ์ฐพ์ ๋ฐฉ๋ฌธํ vertice ๋ฆฌ์คํธ์ ์ถ๊ฐํ๊ณ queue์๋ ์ถ๊ฐํ๋ค.
- ๋ค์ vertex v๋ฅผ ๊ทธ๋ํ์์ ๊ฐ์ ธ์ ๋ฐฉ๋ฌธํ vertice ๋ฆฌ์คํธ์ ์ถ๊ฐํ๋ค.
- v์ ์ธ์ ํ ๋ฐฉ๋ฌธํ์ง ์์ vertice๋ฅผ ๋ชจ๋ queue์ ์ถ๊ฐํ๋ค.
class Graph {
constructor(v){
this.vertices = v;
this.edges = 0;
this.adj = [];
for(let i=0; i<this.vertices;++i){
this.adj[i] = [];
}
this.visited = [];
for(let i=0; i<this.vertices;++i){
this.visited[i] = false;
}
}
// ์ถ๋ ฅ ํฌํผ ํจ์
print(item){
console.log(item);
}
// edge ์ถ๊ธฐ
addEdge(v,w){
this.adj[v].push(w);
this.adj[w].push(v);
this.edges++;
}
// ๊ทธ๋ํ ๊ทธ๋ฆฌ๊ธฐ
showGraph(){
for(let i=0; i< this.vertices; ++i){
this.print(`${i} -> ${this.adj[i].join(', ')}`);
}
}
// dfs
dfs(v){
this.visited[v] = true;
if(this.adj[v] != undefined){
this.print(`visited vertex: ${v}`);
}
this.adj[v].forEach((w)=>{
if(!this.visited[w]){
this.dfs(w);
}
})
}
/////////////////////////// ๐์ถ๊ฐ ///////////////////////////
// bfs
bfs(s){
let queue = [];
this.visited[s] = true;
queue.push(s); // ๋งจ ๋ค์ ์ถ๊ฐ
while(queue.length>0){
let v = queue.shift(); // ๋งจ ์์์ ๊บผ๋ด์ค๊ธฐ
if(v != null){
this.print(`visited vertex : ${v}`);
}
this.adj[v].forEach((w)=>{
if(!this.visited[w]){
this.visited[w]= true;
queue.push(w);
}
})
}
}
/////////////////////////// ๐์ถ๊ฐ ///////////////////////////
}
const graph = new Graph(5);
graph.addEdge(0,1);
graph.addEdge(0,2);
graph.addEdge(1,3);
graph.addEdge(2,4);
graph.showGraph();
graph.bfs(0);
/**
0 -> 1, 2
1 -> 0, 3
2 -> 0, 4
3 -> 1
4 -> 2
visited vertex: 0
visited vertex: 1
visited vertex: 3
visited vertex: 2
visited vertex: 4
*/
dfs bfs ๋น๊ต
๊ทธ๋ํ๋ก ๋ํ๋ด๊ธฐ
0 -> 1, 2
1 -> 0, 3
2 -> 0, 4
3 -> 1
4 -> 2
3๏ธโฃ
b ⁄
1๏ธโฃ
a ⁄
0๏ธโฃ
๏ผผ c
2๏ธโฃ
๏ผผ d
4๏ธโฃ
dfs
vertex ๋ฐฉ๋ฌธ ์์ : 0 1 3 2 4
edge : a b c d
bfs
vertex ๋ฐฉ๋ฌธ ์์ : 0 1 2 3 4
edge : a c b d
์ต๋จ ๊ฑฐ๋ฆฌ ๊ตฌํ๊ธฐ
๊ทธ๋ํ ์ฐ์ฐ ์ค ๊ฐ์ฅ ํํ๊ฒ ์ฌ์ฉ๋๋ ๊ฒ์ ๋ vertex ๊ฐ์ ์ต๋จ ๊ฑฐ๋ฆฌ๋ฅผ ๊ตฌํ๋ ๊ฒ์ด๋ค.
๐๏ธ ์ ๋ฝ์ผ๋ก ํด๊ฐ๋ฅผ ๊ฐ๋ค๊ณ ์๊ฐํด ๋ณด์.
ํ๋ฆฌ, ์ค์์ค ์ค์คํธ๋ฆฌ์, ๋ฒ ๋ค์น์, ํ๋ก๋ ์ค, ๋ก๋ง๋ฅผ ๋ชจ๋ ๋ฐฉ๋ฌธํ๊ณ ์ถ์๋ฐ
2์ฃผ ์์ ์ต๋ํ ์ ์ ๊ฑฐ๋ฆฌ๋ก ๋ฐฉ๋ฌธํ ์ ์๋ ๋ฐฉ๋ฒ์ด ๋ญ๊น?
์ต๋จ ๊ฑฐ๋ฆฌ ์๊ณ ๋ฆฌ์ฆ์ ํ์ฉํด ๋ณธ๋ค๋ฉด ๊ฐ์ผ ํ๋ ๊ฑฐ๋ฆฌ๋ฅผ ์ต์ํํด ๋ณผ ์ ์๋ค.
BFS๋ก ์ต๋จ ๊ฑฐ๋ฆฌ ์ฐพ๊ธฐ
bfs์ ๊ฒฝ์ฐ ์๋์ผ๋ก ํ๋์ vertex์์ ๋ค๋ฅธ vertex๋ก ๊ฐ๋ ์ต๋จ ๊ฑฐ๋ฆฌ๋ฅผ ์ฐพ๊ฒ ๋๋ค.
์๋ฅผ ๋ค์ด A vertex์์ D๋ก ๊ฐ๋ ์ต๋จ ๊ฑฐ๋ฆฌ๋ฅผ ๊ตฌํ ๋, ๋ vertex๋ก ๊ฐ๋ฅ edge๊ฐ 1๊ฐ์ธ ๊ฒฝ์ฐ๋ถํฐ ๊ทธ๋ค์์๋ 2๊ฐ์ธ ๊ฒฝ์ฐ ๊ทธ๋ค์์ 3๊ฐ... ์ด๋ฐ ๋ฐฉ์์ผ๋ก ๊ฑฐ๋ฆฌ๋ฅผ ๊ตฌํ๋ค. bfs๊ฐ ๋์ํ๋ ๋ฐฉ์๊ณผ ๋์ผํ๊ธฐ ๋๋ฌธ์ bfs๋ฅผ ์กฐ๊ธ ์์ ํด์ ์ต๋จ ๊ฑฐ๋ฆฌ ์๊ณ ๋ฆฌ์ฆ์ ๊ตฌํํด ๋ณด์.
class Graph {
constructor(v){
this.vertices = v;
this.edges = 0;
this.adj = [];
for(let i=0; i<this.vertices; ++i){
this.adj[i] = [];
}
this.visited = [];
for(let i=0; i<this.vertices; ++i){
this.visited[i] = false;
}
this.edgeTo = [];
}
// ์ถ๋ ฅ ํฌํผ ํจ์
print(item){
console.log(item);
}
// edge ์ถ๊ฐ
addEdge(v, w){
this.adj[v].push(w);
this.adj[w].push(v);
this.edges++;
}
// ๊ทธ๋ํ ๊ทธ๋ฆฌ๊ธฐ
showGraph(){
for(let i=0; i< this.vertices; ++i){
this.print(`${i} -> ${this.adj[i].join(', ')}`);
}
}
// dfs
dfs(v){
this.visited[v] = true;
if(this.adj[v] != undefined){
this.print(`visited vertex: ${v}`);
}
this.adj[v].forEach((w)=>{
if(!this.visited[w]){
this.dfs(w);
}
});
}
// bfs
bfs(s){
let queue = [];
this.visited[s] = true;
queue.push(s); // ๋งจ ๋ค์ ์ถ๊ฐ
while(queue.length > 0){
let v = queue.shift(); // ๋งจ ์์์ ๊บผ๋ด์ค๊ธฐ
if(v != null){
this.print(`visited vertex: ${v}`);
}
this.adj[v].forEach((w)=>{
if(!this.visited[w]){
this.edgeTo[w] = v;
this.visited[w] = true;
queue.push(w);
}
});
}
}
/////////////////////////// ๐์ถ๊ฐ ///////////////////////////
// ๋ฐฉ๋ฌธ ์ฌ๋ถ ๋ฆฌํด ํฌํผ ํจ์
hasPathTo(v) {
return this.visited[v];
}
// ์์์ ์์ ๋ชฉ์ ์ง๊น์ง์ path
pathTo(v){
let source = 0;
if(!this.hasPathTo(v)){
return undefined;
}
let path = [];
for(let i = v; i != source; i = this.edgeTo[i]){
path.push(i);
}
path.push(source); // source๋ฅผ path์ ์ถ๊ฐ
return path.reverse(); // source์์ destination ๊น์ง์ path
}
/////////////////////////// ๐์ถ๊ฐ ///////////////////////////
}
const graph = new Graph(5);
graph.addEdge(0,1);
graph.addEdge(0,2);
graph.addEdge(1,3);
graph.addEdge(2,4);
// 0๋ถํฐ bfs
graph.bfs(0);
let vertex = 4;
let paths = graph.pathTo(vertex);
if (paths) {
let pathString = paths.join('-');
graph.print(pathString);
} else {
graph.print("No path found");
}
/**
Expected output:
0-2-4
*/
Topological Sorting (์์ ์ ๋ ฌ)
์์์ ๋ ฌ์ ๋ฐฉํฅ์ด ์๋ ๊ทธ๋ํ์ vertice๋ค์ ์ ๋ ฌํ ๊ฑด๋ฐ, ๊ฐ๋ฆฌํค๊ณ ์๋ vertice๋ค์ด ์๋ค๋ฉด ๋จผ์ ์์น์ํค๊ณ , ๋ค๋ฅธ vertex๊ฐ ๊ฐ๋ฆฌํค๊ณ ์๋ vertex๋ค์ ๋ชจ๋ ์ดํ์ ์ ๋ ฌํ๋ ๋ฐฉ์์ด๋ค.
์์ ์ ๋ ฌ์ ํ๋ฉด ๊ทธ๋ํ๋ ๋ค์๊ณผ ๊ฐ๋ค.
- CS1
- CS2
- Assembly language
- Data structures
- Operating systems
- Algorithms
3๋ฒ ์์ (Assembly language)์ 4๋ฒ ์์ (Data structure)์ ๋์์ ์๊ฐ์ด ๊ฐ๋ฅํ๊ณ , 5๋ฒ ์์ (Operating systems)์ 6๋ฒ ์์ (Algorithms)๋ ๋์์ ์๊ฐ์ด ๊ฐ๋ฅํ๋ค. ํ์ง๋ง CS2๋ฅผ ์๊ฐํ์ง ์๊ณ ์๋ Data structures๋ฅผ ์๊ฐํ ์๋ ์๋ค.
์ด ๋ฌธ์ ๋ฅผ precedence-constrained scheduling๋ผ๊ณ ํ๋ค.
์์ ์ ๋ ฌ ์๊ณ ๋ฆฌ์ฆ์ dfs์ ๋น์ทํ๋ค. ํ์ง๋ง ๋ฐฉ๋ฌธํ vertex๋ฅผ ๋ฐ๋ก ์ถ๋ ฅํ๋ ๋์
ํ์ฌ vertex์ ์ธ์ ํ vertice๋ฅผ ๋ชจ๋ ๋ฐฉ๋ฌธํ๊ณ ๋์ ํ์ฌ vertex๋ฅผ ์คํ์ ์ถ๊ฐํ๋ ๋ฐฉ์์ด๋ค.
์์์ ๋ ฌ ์๊ณ ๋ฆฌ์ฆ์ ๋ ๊ฐ์ ๋ฉ์๋๊ฐ ํต์ฌ์ด๋ค.
- topSort : ์ ๋ ฌ ๊ณผ์ ์ ํ๋ topSortHelper๋ฅผ ํธ์ถํ๋ ํฌํผ ํจ์
- topSortHelper : ์ ๋ ฌ๋ vertice๋ค ๋ฆฌ์คํธ๋ฅผ ๋ณด์ฌ์ค๋ค. ํ์ฌ vertex๋ฅผ ๋ฐฉ๋ฌธ ์ฒ๋ฆฌํ๊ณ ์ฌ๊ท์ ์ผ๋ก ํ์ฌ vertex์ ์ธ์ ๋ฆฌ์คํธ์ ์ธ์ ํ vertex๋ฅผ ๋ฐฉ๋ฌธํ๊ณ ๋ฐฉ๋ฌธ์ฒ๋ฆฌ๋ฅผ ํ๋ค. ๋ง์ง๋ง์ผ๋ก ํ์ฌ vertex๋ฅผ ์คํ์ ์ถ๊ฐํ๋ค.
class Graph {
constructor(v){
this.vertices = v;
this.edges = 0;
this.adj = [];
for(let i = 0; i < this.vertices; ++i){
this.adj[i] = [];
}
this.visited = [];
for(let i = 0; i < this.vertices; ++i){
this.visited[i] = false;
}
this.edgeTo = [];
this.vertexList = [];
}
print(item){
console.log(item);
}
addEdge(v, w){
this.adj[v].push(w);
this.edges++;
}
addVertex(v){
this.vertexList.push(v);
}
showGraph(){
for(let i = 0; i < this.vertices; ++i){
this.print(`${this.vertexList[i]} -> ${this.adj[i].map(v => this.vertexList[v]).join(', ')}`);
}
}
dfs(v){
this.visited[v] = true;
if(this.adj[v] != undefined){
this.print(`visited vertex: ${this.vertexList[v]}`);
}
this.adj[v].forEach((w) => {
if(!this.visited[w]){
this.dfs(w);
}
});
}
bfs(s){
let queue = [];
this.visited[s] = true;
queue.push(s);
while(queue.length > 0){
let v = queue.shift();
if(v != null){
this.print(`visited vertex: ${this.vertexList[v]}`);
}
this.adj[v].forEach((w) => {
if(!this.visited[w]){
this.edgeTo[w] = v;
this.visited[w] = true;
queue.push(w);
}
});
}
}
// vertex๋ก ๊ฐ๋ path ์๋ ์ง ํ์ธํ๋ ํฌํผ ํจ์
hasPathTo(v) {
return this.visited[v];
}
// vertex๋ก๊ฐ๋ path ๊ตฌํ๊ธฐ
pathTo(v){
let source = 0;
if(!this.hasPathTo(v)){
return undefined;
}
let path = [];
for(let i = v; i != source; i = this.edgeTo[i]){
path.push(i);
}
path.push(source); // source๋ก๊ฐ๋ path ์ถ๊ฐ
return path.reverse(); // source์์ destination ๊ฐ๋ Path
}
/////////////////////////// ๐์ถ๊ฐ ///////////////////////////
// Topological sort
topSort(){
let stack = [];
let visited = new Array(this.vertices).fill(false);
for (let i = 0; i < this.vertices; i++) {
if (visited[i] == false) {
this.topSortHelper(i, visited, stack);
}
}
while(stack.length > 0) {
this.print(this.vertexList[stack.pop()]);
}
}
topSortHelper(v, visited, stack) {
visited[v] = true;
this.adj[v].forEach((w) => {
if(!visited[w]){
this.topSortHelper(w, visited, stack);
}
});
stack.push(v);
}
/////////////////////////// ๐์ถ๊ฐ ///////////////////////////
}
const graph = new Graph(6);
graph.addVertex("CS1"); // 0
graph.addVertex("CS2"); // 1
graph.addVertex("Data Structures"); // 2
graph.addVertex("Assembly Language"); // 3
graph.addVertex("Operating Systems"); //4
graph.addVertex("Algorithms"); // 5
graph.addEdge(0, 1);
graph.addEdge(1, 2);
graph.addEdge(1, 3);
graph.addEdge(2, 4);
graph.addEdge(2, 5);
graph.topSort();
/**
CS1
CS2
Assembly Language
Data Structures
Algorithms
Operating Systems
*/
๐ Reference
- Data Structures and Algorithms Using Javaโ Script by Michael McMillian (O’Reilly). Copyright 2014 Michael McMillan, 978-1-449-36493-9