diff --git a/README.md b/README.md
index 51abd25..36bb89b 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,92 @@
-# javascript-subway-final
\ No newline at end of file
+# ๐ ์งํ์ฒ ๋
ธ์ ๋ ๊ฒฝ๋ก ์กฐํ ๋ฏธ์
+
+- ๋ฑ๋ก๋ ์งํ์ฒ ๋
ธ์ ๋์์ ๊ฒฝ๋ก๋ฅผ ์กฐํํ๋ ๊ธฐ๋ฅ์ ๊ตฌํํ๋ค.
+
+### URL
+
+#### https://yungo1846.github.io/javascript-subway-path-precourse/
+
+### ๋๋ ํ ๋ฆฌ ๊ตฌ์กฐ
+
+```bash
+โ index.html
+โ README.md
+โ
+โโimages
+โ dijkstra_example.png
+โ path_result.gif
+โ path_result.jpg
+โ
+โโsrc
+ โ index.js
+ โ
+ โโcommon
+ โ alertMessage.js
+ โ checkInput.js
+ โ constant.js
+ โ StationInfo.js
+ โ
+ โโevents
+ โ FindRoadEvent.js
+ โ
+ โโrenders
+ โ renderRoadResult.js
+ โ
+ โโutils
+ Dijkstra.js
+```
+
+### ์ด๊ธฐ ์ค์
+
+- ํ๋ก๊ทธ๋จ ์์ ์ ์ญ, ๋
ธ์ , ๊ตฌ๊ฐ ๋ฐ์ดํฐ๋ฅผ ์ด๊ธฐ ์ค์ ํด์ผ ํ๋ค.
+- ๊ฑฐ๋ฆฌ์ ์์ ์๊ฐ์ ์์ ์ ์์ด๋ฉฐ ๋จ์๋ km์ ๋ถ์ ์๋ฏธํ๋ค.
+- ์๋ฌด ์ญ๊ณผ๋ ์ฐ๊ฒฐ๋์ด ์์ง ์์ '์ํ์ญ' ์ถ๊ฐ (์์ธ์ฌํญ ํ
์คํธ์ฉ)
+- ์๋์ ์ฌ์ ๋ฑ๋ก ์ ๋ณด๋ก ๋ฐ๋์ ์ด๊ธฐ ์ค์ ์ ํ๋ค.
+
+```
+1. ์งํ์ฒ ์ญ์ผ๋ก ๊ต๋, ๊ฐ๋จ, ์ญ์ผ, ๋จ๋ถํฐ๋ฏธ๋, ์์ฌ, ์์ฌ์๋ฏผ์์ฒ, ๋งค๋ด ์ญ ์ ๋ณด๊ฐ ๋ฑ๋ก๋์ด ์๋ค.
+2. ์งํ์ฒ ๋
ธ์ ์ผ๋ก 2ํธ์ , 3ํธ์ , ์ ๋ถ๋น์ ์ด ๋ฑ๋ก๋์ด ์๋ค.
+3. ๋
ธ์ ์ ์ญ์ด ์๋์ ๊ฐ์ด ๋ฑ๋ก๋์ด ์๋ค.(์ผ์ชฝ ๋์ด ์ํ ์ข
์ )
+ - 2ํธ์ : ๊ต๋ - ( 2km / 3๋ถ ) - ๊ฐ๋จ - ( 2km / 3๋ถ ) - ์ญ์ผ
+ - 3ํธ์ : ๊ต๋ - ( 3km / 2๋ถ ) - ๋จ๋ถํฐ๋ฏธ๋ - ( 6km / 5๋ถ ) - ์์ฌ - ( 1km / 1๋ถ ) - ๋งค๋ด
+ - ์ ๋ถ๋น์ : ๊ฐ๋จ - ( 2km / 8๋ถ ) - ์์ฌ - ( 10km / 3๋ถ ) - ์์ฌ์๋ฏผ์์ฒ
+ - ์ํ์ญ
+```
+
+### ๊ฒฝ๋ก ์กฐํ ๊ธฐ๋ฅ
+
+
+
+- ์ถ๋ฐ์ญ๊ณผ ๋์ฐฉ์ญ์ ์
๋ ฅ๋ฐ์ ๊ฒฝ๋ก๋ฅผ ์กฐํํ๋ค. (์๋ฃ)
+- ๊ฒฝ๋ก ์กฐํ ์ ์ด ๊ฑฐ๋ฆฌ, ์ด ์์ ์๊ฐ์ ํจ๊ป ์ถ๋ ฅํ๋ค. (์๋ฃ)
+- ๊ฒฝ๋ก ์กฐํ ์ `์ต๋จ ๊ฑฐ๋ฆฌ` ๋๋ `์ต์ ์๊ฐ` ์ต์
์ ์ ํํ ์ ์๋ค. (์๋ฃ)
+
+### ์์ธ ์ฒ๋ฆฌ
+
+- ์ถ๋ฐ์ญ๊ณผ ๋์ฐฉ์ญ์ 2๊ธ์ ์ด์์ด์ด์ผ ํ๋ค. (์๋ฃ)
+- ์กด์ฌํ์ง ์๋ ์ญ์ ์ถ๋ฐ์ญ ๋๋ ๋์ฐฉ์ญ์ผ๋ก ์
๋ ฅํ ์ ์๋ค. (์๋ฃ)
+- ๊ฒฝ๋ก ์กฐํ ์ ์ถ๋ฐ์ญ๊ณผ ๋์ฐฉ์ญ์ด ๊ฐ์ ์ ์๋ค. (์๋ฃ)
+- ๊ฒฝ๋ก ์กฐํ ์ ์ถ๋ฐ์ญ๊ณผ ๋์ฐฉ์ญ์ด ์ฐ๊ฒฐ๋์ง ์์ผ๋ฉด ๊ฒฝ๋ก๋ฅผ ์กฐํํ ์ ์๋ค. (์๋ฃ)
+
+ => ๊ธฐ๋ณธ ๋
ธ์ ์ ๋ณด์ ์๋ฌด ์ญ๊ณผ๋ ์ฐ๊ฒฐ๋์์ง ์์ ์ํ์ญ์ ์
๋ ฅํ์ฌ ํ์ธ ๊ฐ๋ฅ
+
+- ๊ทธ ์ธ ์ ์์ ์ผ๋ก ํ๋ก๊ทธ๋จ์ด ์ํ๋์ง ์์ ๊ฒฝ์ฐ `alert`์ผ๋ก ์๋ฌ๋ฅผ ์ถ๋ ฅํ๋ค. (์๋ฃ)
+
+
+
+## ๐ป ํ๋ก๊ทธ๋๋ฐ ์คํ ๊ฒฐ๊ณผ
+
+### ๊ฒฝ๋ก ์กฐํ
+
+
+
+## โ
ํ๋ก๊ทธ๋๋ฐ ์๊ตฌ์ฌํญ
+
+### ๊ธธ์ฐพ๊ธฐ ๊ด๋ จ ๊ธฐ๋ฅ
+
+- ์ถ๋ฐ์ญ์ ์
๋ ฅํ๋ input ํ๊ทธ๋ `departure-station-name-input` id ์์ฑ๊ฐ์ ๊ฐ์ง๋ค.
+- ๋์ฐฉ์ญ์ ์
๋ ฅํ๋ input ํ๊ทธ๋ `arrival-station-name-input` id ์์ฑ๊ฐ์ ๊ฐ์ง๋ค.
+- ์ต๋จ๊ฑฐ๋ฆฌ, ์ต์์๊ฐ์ ์ ํํ๋ radio๋ `search-type` name ์์ฑ๊ฐ์ ๊ฐ์ง๋ค.
+ - **radio option์ default ๊ฐ์ ์ต๋จ๊ฑฐ๋ฆฌ์ด๋ค.**
+- ๊ธธ์ฐพ๊ธฐ ๋ฒํผ์ `search-button` id ์์ฑ๊ฐ์ ๊ฐ์ง๋ค.
+- ๐ ๊ฒฐ๊ณผ๋ `table`์ ์ด์ฉํ์ฌ ๋ณด์ฌ์ค๋ค.
diff --git a/images/dijkstra_example.png b/images/dijkstra_example.png
new file mode 100644
index 0000000..7c75197
Binary files /dev/null and b/images/dijkstra_example.png differ
diff --git a/images/path_result.gif b/images/path_result.gif
new file mode 100644
index 0000000..ee394bd
Binary files /dev/null and b/images/path_result.gif differ
diff --git a/images/path_result.jpg b/images/path_result.jpg
new file mode 100644
index 0000000..40a4bed
Binary files /dev/null and b/images/path_result.jpg differ
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..468a5fb
--- /dev/null
+++ b/index.html
@@ -0,0 +1,37 @@
+
+
+
+
+ ์งํ์ฒ ๊ธธ์ฐพ๊ธฐ
+
+
+
+
+
+
+
diff --git a/src/common/StationInfo.js b/src/common/StationInfo.js
new file mode 100644
index 0000000..e1deedc
--- /dev/null
+++ b/src/common/StationInfo.js
@@ -0,0 +1,36 @@
+export const stations = [
+ { name: "๊ต๋" },
+ { name: "๊ฐ๋จ" },
+ { name: "์ญ์ผ" },
+ { name: "๋จ๋ถํฐ๋ฏธ๋" },
+ { name: "์์ฌ" },
+ { name: "๋งค๋ด" },
+ { name: "์์ฌ์๋ฏผ์์ฒ" },
+ { name: "์ํ" }, // island node to test none connected stations
+];
+
+// sections: [์ถ๋ฐ์ญ, ๋ค์์ญ, ๊ฑฐ๋ฆฌ, ์์์๊ฐ]
+export const lines = [
+ {
+ name: "2ํธ์ ",
+ sections: [
+ ["๊ต๋", "๊ฐ๋จ", 2, 3],
+ ["๊ฐ๋จ", "์ญ์ผ", 2, 3],
+ ],
+ },
+ {
+ name: "3ํธ์ ",
+ sections: [
+ ["๊ต๋", "๋จ๋ถํฐ๋ฏธ๋", 3, 2],
+ ["๋จ๋ถํฐ๋ฏธ๋", "์์ฌ", 6, 5],
+ ["์์ฌ", "๋งค๋ด", 1, 1],
+ ],
+ },
+ {
+ name: "์ ๋ถ๋น์ ",
+ sections: [
+ ["๊ฐ๋จ", "์์ฌ", 2, 8],
+ ["์์ฌ", "์์ฌ์๋ฏผ์์ฒ", 10, 3],
+ ],
+ },
+];
diff --git a/src/common/alertMessage.js b/src/common/alertMessage.js
new file mode 100644
index 0000000..a50671b
--- /dev/null
+++ b/src/common/alertMessage.js
@@ -0,0 +1,9 @@
+import { constant } from "./constant.js";
+
+export const alertMessage = {
+ SHORT_LENGTH_ERROR: `์ญ ์ด๋ฆ์ ์ต์ ${constant.minLength} ๊ธ์ ์ด์ ์
๋ ฅํด์ผ ํฉ๋๋ค.`,
+ SAME_DESTINATION_ERROR: `์ถ๋ฐ์ญ๊ณผ ๋์ฐฉ์ญ์ด ๊ฐ์ต๋๋ค`,
+ NONE_SELECTED_RADIO: `์ต๋จ๊ฑฐ๋ฆฌ์ ์ต์์๊ฐ ์ค ํ๋๋ฅผ ์ ํํด์ฃผ์ธ์!`,
+ NOT_EXIST_STATION: `์กด์ฌํ์ง ์๋ ์ญ์ด ์
๋ ฅ๋์์ต๋๋ค.`,
+ NOT_CONNECTED_LINE: `์ถ๋ฐ์ญ๊ณผ ๋์ฐฉ์ญ์ด ์๋ก ์ฐ๊ฒฐ๋์ด ์์ง ์์ต๋๋ค.`,
+};
diff --git a/src/common/checkInput.js b/src/common/checkInput.js
new file mode 100644
index 0000000..a65cc47
--- /dev/null
+++ b/src/common/checkInput.js
@@ -0,0 +1,18 @@
+import { constant } from "./constant.js";
+export function isSatisfyLength(len) {
+ if (String(len).length < constant.minLength) {
+ return false;
+ }
+
+ return true;
+}
+
+export function isExistStation(stations, station) {
+ for (let i = 0; i < stations.length; i++) {
+ if (station === stations[i].name) {
+ return true;
+ }
+ }
+
+ return false;
+}
diff --git a/src/common/constant.js b/src/common/constant.js
new file mode 100644
index 0000000..c8f9579
--- /dev/null
+++ b/src/common/constant.js
@@ -0,0 +1,3 @@
+export const constant = {
+ minLength: 2,
+};
diff --git a/src/events/FindRoadEvent.js b/src/events/FindRoadEvent.js
new file mode 100644
index 0000000..3d9b0ad
--- /dev/null
+++ b/src/events/FindRoadEvent.js
@@ -0,0 +1,126 @@
+import Dijkstra from "../utils/Dijkstra.js";
+import renderRoadResult from "../renders/renderRoadResult.js";
+import { alertMessage } from "../common/alertMessage.js";
+import { stations, lines } from "../common/StationInfo.js";
+import { isSatisfyLength, isExistStation } from "../common/checkInput.js";
+
+export default function FindRoadEvent() {
+ const dijkstra = new Dijkstra();
+ const startStation = document.getElementById("departure-station-name-input").value;
+ const endStation = document.getElementById("arrival-station-name-input").value;
+ const information = whichRadioChecked();
+ if (!isValidInput()) {
+ return;
+ }
+ const shortestPath = getShortestPath(startStation, endStation);
+ if (!isStationsConneted()) {
+ return;
+ }
+ const totalWeight = getShortestWeight(shortestPath);
+ const totalDistance = totalWeight[0];
+ const totalTime = totalWeight[1];
+ renderRoadResult(information, shortestPath, totalDistance, totalTime);
+
+ function isValidInput() {
+ if (!isSatisfyLength(startStation) || !isSatisfyLength(endStation)) {
+ alert(alertMessage.SHORT_LENGTH_ERROR);
+ return false;
+ } else if (startStation === endStation) {
+ alert(alertMessage.SAME_DESTINATION_ERROR);
+ return false;
+ } else if (!isExistStation(stations, startStation) || !isExistStation(stations, endStation)) {
+ alert(alertMessage.NOT_EXIST_STATION);
+ return false;
+ } else if (information === undefined) {
+ alert(alertMessage.NONE_SELECTED_RADIO);
+ return false;
+ }
+ return true;
+ }
+
+ function whichRadioChecked() {
+ const shortestPathRadio = document.getElementById("shortest-path-radio");
+ const minTimeRadio = document.getElementById("min-time-path-radio");
+
+ if (shortestPathRadio.checked) {
+ return shortestPathRadio.value;
+ } else if (minTimeRadio.checked) {
+ return minTimeRadio.value;
+ } else {
+ return undefined;
+ }
+ }
+
+ function isStationsConneted() {
+ if (shortestPath === undefined) {
+ alert(alertMessage.NOT_CONNECTED_LINE);
+ return false;
+ }
+ return true;
+ }
+
+ function _getShortestPath(i, j, index) {
+ for (let k = 0; k < lines[j].sections.length; k++) {
+ if (stations[i].name === lines[j].sections[k][0]) {
+ dijkstra.addEdge(
+ lines[j].sections[k][0],
+ lines[j].sections[k][1],
+ lines[j].sections[k][index]
+ );
+ }
+ }
+ }
+
+ function getShortestPath(start, end) {
+ let index;
+ if (information == "์ต๋จ๊ฑฐ๋ฆฌ") {
+ index = 2;
+ } else if (information == "์ต์์๊ฐ") {
+ index = 3;
+ }
+ for (let i = 0; i < stations.length; i++) {
+ for (let j = 0; j < lines.length; j++) {
+ _getShortestPath(i, j, index);
+ }
+ }
+
+ return dijkstra.findShortestPath(start, end);
+ }
+
+ function _getShortestWeight(shortestPath, i, j) {
+ let _distance = 0;
+ let _time = 0;
+ for (let k = 0; k < lines[j].sections.length; k++) {
+ if (
+ lines[j].sections[k][0] === shortestPath[i] &&
+ lines[j].sections[k][1] === shortestPath[i + 1]
+ ) {
+ _distance += lines[j].sections[k][2];
+ _time += lines[j].sections[k][3];
+ } else if (
+ lines[j].sections[k][1] === shortestPath[i] &&
+ lines[j].sections[k][0] === shortestPath[i + 1]
+ ) {
+ _distance += lines[j].sections[k][2];
+ _time += lines[j].sections[k][3];
+ }
+ }
+
+ return [_distance, _time];
+ }
+
+ function getShortestWeight(shortestPath) {
+ let distance = 0;
+ let time = 0;
+ let temp;
+ for (let i = 0; i < shortestPath.length; i++) {
+ for (let j = 0; j < lines.length; j++) {
+ temp = _getShortestWeight(shortestPath, i, j);
+ distance += temp[0];
+ time += temp[1];
+ }
+ }
+
+ return [distance, time];
+ }
+}
diff --git a/src/index.js b/src/index.js
new file mode 100644
index 0000000..95ad37a
--- /dev/null
+++ b/src/index.js
@@ -0,0 +1,8 @@
+import FindRoadEvent from "./events/FindRoadEvent.js";
+
+export default function SubwayNavigation() {
+ const inputButton = document.getElementById("search-button");
+ inputButton.addEventListener("click", FindRoadEvent);
+}
+
+new SubwayNavigation();
diff --git a/src/renders/renderRoadResult.js b/src/renders/renderRoadResult.js
new file mode 100644
index 0000000..3efdf92
--- /dev/null
+++ b/src/renders/renderRoadResult.js
@@ -0,0 +1,46 @@
+function resultContainerTemplate(information, result) {
+ return `๐๊ฒฐ๊ณผ
+ ${information}
+
+
+ | ์ด ๊ฑฐ๋ฆฌ |
+ ์ด ์์ ์๊ฐ |
+
+
`;
+}
+
+function initResultContainer(information) {
+ const resultContainer = document.getElementById("result-container");
+ resultContainer.innerHTML = resultContainerTemplate(information);
+}
+
+function resultListTemplate(shortestPath, totalDistance, totalTime) {
+ return `
+ |
+ ${totalDistance}Km
+ |
+
+ ${totalTime}๋ถ
+ |
+
+
+ |
+ ${shortestPath
+ .map((station, i) => (i !== shortestPath.length - 1 ? station + "=>" : station))
+ .join("")}
+ |
+
`;
+}
+
+function initResultList(shortestPath, totalDistance, totalTime) {
+ const resultTable = document.getElementById("result-table");
+ resultTable.insertAdjacentHTML(
+ "beforeend",
+ resultListTemplate(shortestPath, totalDistance, totalTime)
+ );
+}
+
+export default function renderRoadResult(information, shortestPath, totalDistance, totalTime) {
+ initResultContainer(information);
+ initResultList(shortestPath, totalDistance, totalTime);
+}
diff --git a/src/utils/Dijkstra.js b/src/utils/Dijkstra.js
new file mode 100644
index 0000000..3cf4a81
--- /dev/null
+++ b/src/utils/Dijkstra.js
@@ -0,0 +1,212 @@
+export default function Dijkstra() {
+ const Node = {
+ init: function (val, priority) {
+ this.val = val;
+ this.priority = priority;
+ },
+ };
+
+ const PriorityQueue = {
+ init: function () {
+ this.values = [];
+ },
+ enqueue: function (val, priority) {
+ const newNode = Object.create(Node);
+ newNode.init(val, priority);
+
+ this.values.push(newNode);
+
+ let idxOfNewNode = this.values.length - 1;
+
+ while (idxOfNewNode > 0) {
+ const idxOfParentNode = Math.floor((idxOfNewNode - 1) / 2);
+
+ const parentNode = this.values[idxOfParentNode];
+
+ if (priority < parentNode.priority) {
+ this.values[idxOfParentNode] = newNode;
+ this.values[idxOfNewNode] = parentNode;
+ idxOfNewNode = idxOfParentNode;
+ continue;
+ }
+ break;
+ }
+ return this.values;
+ },
+ dequeue: function () {
+ if (this.values.length == 0) {
+ return;
+ }
+ const dequeued = this.values.shift();
+ const lastItem = this.values.pop();
+ if (!lastItem) {
+ return dequeued;
+ }
+ this.values.unshift(lastItem);
+
+ let idxOfTarget = 0;
+
+ while (true) {
+ let idxOfLeftChild = idxOfTarget * 2 + 1;
+ let idxOfRightChild = idxOfTarget * 2 + 2;
+ let leftChild = this.values[idxOfLeftChild];
+ let rightChild = this.values[idxOfRightChild];
+
+ function swap(direction) {
+ const idxOfChild = direction == "left" ? idxOfLeftChild : idxOfRightChild;
+ const child = direction == "left" ? leftChild : rightChild;
+ this.values[idxOfChild] = this.values[idxOfTarget];
+ this.values[idxOfTarget] = child;
+ idxOfTarget = idxOfChild;
+ }
+
+ if (!leftChild) {
+ return dequeued;
+ }
+
+ if (!rightChild) {
+ if (leftChild.priority < lastItem.priority) {
+ swap.call(this, "left");
+ continue;
+ }
+ return dequeued;
+ }
+
+ if (leftChild.priority == rightChild.priority) {
+ swap.call(this, "left");
+ continue;
+ }
+
+ if (leftChild.priority < rightChild.priority && leftChild.priority < lastItem.priority) {
+ swap.call(this, "left");
+ continue;
+ }
+
+ if (rightChild.priority < leftChild.priority && rightChild.priority < lastItem.priority) {
+ swap.call(this, "right");
+ continue;
+ }
+ }
+ },
+ };
+
+ const WeightedGraph = {
+ init: function () {
+ this.adjacencyList = {};
+ this.length = 0;
+ },
+ addVertex: function (vertex) {
+ if (!this.adjacencyList.hasOwnProperty(vertex)) {
+ this.adjacencyList[vertex] = {};
+ this.length++;
+ }
+ },
+ addEdge: function (vertex1, vertex2, weight) {
+ this.addVertex(vertex1);
+ this.addVertex(vertex2);
+ this.adjacencyList[vertex1][vertex2] = weight;
+ this.adjacencyList[vertex2][vertex1] = weight;
+ return this.adjacencyList;
+ },
+ removeEdge: function (vertex1, vertex2) {
+ if (!this.adjacencyList.hasOwnProperty(vertex1)) {
+ return `There's no ${vertex1}`;
+ }
+ if (!this.adjacencyList.hasOwnProperty(vertex2)) {
+ return `There's no ${vertex2}`;
+ }
+
+ function removeHelper(v1, v2) {
+ if (!this.adjacencyList.hasOwnProperty(v1)) {
+ return `There's no edge between ${v1} and ${v2}`;
+ }
+ delete this.adjacencyList[v1][v2];
+ if (Object.keys(this.adjacencyList[v1]).length == 0) {
+ delete this.adjacencyList[v1];
+ }
+ }
+
+ removeHelper.call(this, vertex1, vertex2);
+ removeHelper.call(this, vertex2, vertex1);
+
+ return this.adjacencyList;
+ },
+ removeVertex: function (vertex) {
+ if (!this.adjacencyList.hasOwnProperty(vertex)) {
+ return `There's no ${vertex}`;
+ }
+ const edges = this.adjacencyList[vertex];
+ for (const key in edges) {
+ this.removeEdge(key, vertex);
+ }
+ return this.adjacencyList;
+ },
+ findShortestRoute: function (start, end) {
+ if (!start || !end) {
+ throw Error("์ถ๋ฐ์ง์ ๋์ฐฉ์ง๋ฅผ ๋ชจ๋ ์
๋ ฅํด์ผ ํฉ๋๋ค.");
+ }
+ const distance = {};
+ const previous = {};
+ const pq = Object.create(PriorityQueue);
+ pq.init();
+ pq.enqueue(start, 0);
+ const visited = {};
+
+ const hashOfVertex = this.adjacencyList;
+ for (const vertexName in hashOfVertex) {
+ const priority = vertexName == start ? 0 : Infinity;
+ distance[vertexName] = priority;
+ previous[vertexName] = null;
+ }
+
+ while (true) {
+ let current = pq.dequeue();
+ if (!current?.val) {
+ return;
+ }
+ current = current.val;
+ if (current == end) {
+ break;
+ }
+ const neighbors = hashOfVertex[current];
+
+ for (const vertexName in neighbors) {
+ if (visited.hasOwnProperty(vertexName)) {
+ continue;
+ }
+ const distFromStart = distance[current] + neighbors[vertexName];
+
+ if (distFromStart < distance[vertexName]) {
+ pq.enqueue(vertexName, distFromStart);
+ distance[vertexName] = distFromStart;
+ previous[vertexName] = current;
+ }
+ }
+ visited[current] = true;
+ }
+
+ let node = end;
+
+ const route = [];
+ while (node) {
+ route.unshift(node);
+ node = previous[node];
+ }
+ return route;
+ },
+ };
+
+ this.addEdge = (source, target, weight) => {
+ WeightedGraph.addEdge(source, target, weight);
+ };
+
+ this.findShortestPath = (source, target) => {
+ return WeightedGraph.findShortestRoute(source, target);
+ };
+
+ this.addVertex = (vertex) => {
+ WeightedGraph.addVertex(vertex);
+ };
+
+ WeightedGraph.init();
+}