Skip to content

Commit 94cbd78

Browse files
committed
refactor: 백준/특정 거리의 도시 찾기 - 최소 heap으로 변경
1 parent b1509e6 commit 94cbd78

1 file changed

Lines changed: 88 additions & 9 deletions

File tree

boj/18352(다익스트라).js

Lines changed: 88 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,95 @@
11
// 특정 거리의 도시 찾기
22
// https://www.acmicpc.net/problem/18352
33

4+
class MinHeap {
5+
constructor() {
6+
this.nodes = [];
7+
}
8+
9+
isEmpty() {
10+
return this.nodes.length === 0;
11+
}
12+
13+
insert(value) {
14+
this.nodes.push(value);
15+
this.bubbleUp();
16+
}
17+
18+
bubbleUp(index = this.nodes.length - 1) {
19+
if (index < 1) return;
20+
21+
const currentNode = this.nodes[index];
22+
const parentIndex = Math.floor((index - 1) / 2);
23+
const parentNode = this.nodes[parentIndex];
24+
25+
if (parentNode[1] <= currentNode[1]) return;
26+
27+
this.nodes[index] = parentNode;
28+
this.nodes[parentIndex] = currentNode;
29+
index = parentIndex;
30+
this.bubbleUp(index);
31+
}
32+
33+
extract() {
34+
const min = this.nodes[0];
35+
if (this.nodes.length === 1) {
36+
this.nodes.pop();
37+
return min;
38+
}
39+
this.nodes[0] = this.nodes.pop();
40+
this.trickleDown();
41+
return min;
42+
}
43+
44+
trickleDown(index = 0) {
45+
const leftChildIndex = 2 * index + 1;
46+
const rightChildIndex = 2 * index + 2;
47+
const length = this.nodes.length;
48+
let minimum = index;
49+
50+
if (!this.nodes[rightChildIndex] && !this.nodes[leftChildIndex]) return;
51+
if (!this.nodes[rightChildIndex]) {
52+
if (this.nodes[leftChildIndex][1] < this.nodes[minimum][1]) {
53+
minimum = leftChildIndex;
54+
}
55+
return;
56+
}
57+
58+
if (this.nodes[leftChildIndex][1] > this.nodes[rightChildIndex][1]) {
59+
if (
60+
rightChildIndex <= length &&
61+
this.nodes[rightChildIndex][1] < this.nodes[minimum][1]
62+
) {
63+
minimum = rightChildIndex;
64+
}
65+
} else {
66+
if (
67+
leftChildIndex <= length &&
68+
this.nodes[leftChildIndex][1] < this.nodes[minimum][1]
69+
) {
70+
minimum = leftChildIndex;
71+
}
72+
}
73+
74+
if (minimum !== index) {
75+
let t = this.nodes[minimum];
76+
this.nodes[minimum] = this.nodes[index];
77+
this.nodes[index] = t;
78+
this.trickleDown(minimum);
79+
}
80+
}
81+
}
82+
483
function dijkstra(N, K, X, graph) {
584
const visit = Array(N + 1).fill(Infinity);
6-
const queue = [];
85+
const heap = new MinHeap();
786

8-
queue.push([X, 0]);
87+
heap.insert([X, 0]);
988

1089
visit[X] = 0;
1190

12-
while (queue.length !== 0) {
13-
queue.sort((a, b) => {
14-
return a[1] - b[1];
15-
});
16-
17-
const [vertex, weight] = queue.shift();
91+
while (!heap.isEmpty()) {
92+
const [vertex, weight] = heap.extract();
1893

1994
if (weight > K) {
2095
continue;
@@ -23,7 +98,7 @@ function dijkstra(N, K, X, graph) {
2398
for (let i = 0; i < graph[vertex].length; i++) {
2499
if (weight + 1 < visit[graph[vertex][i]]) {
25100
visit[graph[vertex][i]] = weight + 1;
26-
queue.push([graph[vertex][i], weight + 1]);
101+
heap.insert([graph[vertex][i], weight + 1]);
27102
}
28103
}
29104
}
@@ -90,6 +165,10 @@ console.log(dijkstra(N, K, X, graph));
90165
91166
자바스크립트에는 기본으로 제공되는 우선순위 큐 자료구조가 없어서 루프를 돌 때 마다 정렬하는 식으로 타협을 봤다.
92167
168+
---
169+
170+
루프돌때 정렬하는 부분에 최소힙을 적용할 수 있을까 싶어서 최소힙을 적용해봤는데 의도한대로 작동하였다.
171+
93172
## Retrospective
94173
95174
*/

0 commit comments

Comments
 (0)