feat: Test running overhaul, switch to Prettier & reformat everything (#1407)

* chore: Switch to Node 20 + Vitest

* chore: migrate to vitest mock functions

* chore: code style (switch to prettier)

* test: re-enable long-running test

Seems the switch to Node 20 and Vitest has vastly improved the code's and / or the test's runtime!

see #1193

* chore: code style

* chore: fix failing tests

* Updated Documentation in README.md

* Update contribution guidelines to state usage of Prettier

* fix: set prettier printWidth back to 80

* chore: apply updated code style automatically

* fix: set prettier line endings to lf again

* chore: apply updated code style automatically

---------

Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com>
Co-authored-by: Lars Müller <34514239+appgurueu@users.noreply.github.com>
This commit is contained in:
Roland Hummel
2023-10-03 23:08:19 +02:00
committed by GitHub
parent 0ca18c2b2c
commit 86d333ee94
392 changed files with 5849 additions and 16622 deletions

View File

@ -25,7 +25,7 @@ Reference:
* @param dest Destination node
* @returns Shortest distance from source to destination
*/
function BellmanFord (graph, V, E, src, dest) {
function BellmanFord(graph, V, E, src, dest) {
// Initialize distance of all vertices as infinite.
const dis = Array(V).fill(Infinity)
// initialize distance of source as 0
@ -36,7 +36,9 @@ function BellmanFord (graph, V, E, src, dest) {
// vertex can have at-most |V| - 1 edges
for (let i = 0; i < V - 1; i++) {
for (let j = 0; j < E; j++) {
if ((dis[graph[j][0]] + graph[j][2]) < dis[graph[j][1]]) { dis[graph[j][1]] = dis[graph[j][0]] + graph[j][2] }
if (dis[graph[j][0]] + graph[j][2] < dis[graph[j][1]]) {
dis[graph[j][1]] = dis[graph[j][0]] + graph[j][2]
}
}
}
// check for negative-weight cycles.
@ -44,7 +46,7 @@ function BellmanFord (graph, V, E, src, dest) {
const x = graph[i][0]
const y = graph[i][1]
const weight = graph[i][2]
if ((dis[x] !== Infinity) && (dis[x] + weight < dis[y])) {
if (dis[x] !== Infinity && dis[x] + weight < dis[y]) {
return null
}
}

View File

@ -10,7 +10,7 @@
*/
export class BinaryLifting {
constructor (root, tree) {
constructor(root, tree) {
this.root = root
this.connections = new Map()
this.up = new Map() // up[node][i] stores the 2^i-th parent of node
@ -21,12 +21,12 @@ export class BinaryLifting {
this.dfs(root, root)
}
addNode (node) {
addNode(node) {
// Function to add a node to the tree (connection represented by set)
this.connections.set(node, new Set())
}
addEdge (node1, node2) {
addEdge(node1, node2) {
// Function to add an edge (adds the node too if they are not present in the tree)
if (!this.connections.has(node1)) {
this.addNode(node1)
@ -38,7 +38,7 @@ export class BinaryLifting {
this.connections.get(node2).add(node1)
}
dfs (node, parent) {
dfs(node, parent) {
// The dfs function calculates 2^i-th ancestor of all nodes for i ranging from 0 to this.log
// We make use of the fact the two consecutive jumps of length 2^(i-1) make the total jump length 2^i
this.up.set(node, new Map())
@ -53,7 +53,7 @@ export class BinaryLifting {
}
}
kthAncestor (node, k) {
kthAncestor(node, k) {
// if value of k is more than or equal to the number of total nodes, we return the root of the graph
if (k >= this.connections.size) {
return this.root
@ -69,7 +69,7 @@ export class BinaryLifting {
}
}
function binaryLifting (root, tree, queries) {
function binaryLifting(root, tree, queries) {
const graphObject = new BinaryLifting(root, tree)
const ancestors = []
for (const [node, k] of queries) {

View File

@ -1,37 +1,37 @@
import Queue from '../Data-Structures/Queue/Queue'
/**
* Breadth-first search is an algorithm for traversing a graph.
*
* It discovers all nodes reachable from the starting position by exploring all of the neighbor nodes at the present
* depth prior to moving on to the nodes at the next depth level.
*
* (description adapted from https://en.wikipedia.org/wiki/Breadth-first_search)
* @see https://www.koderdojo.com/blog/breadth-first-search-and-shortest-path-in-csharp-and-net-core
*/
export function breadthFirstSearch (graph, startingNode) {
// visited keeps track of all nodes visited
const visited = new Set()
// queue contains the nodes to be explored in the future
const queue = new Queue()
queue.enqueue(startingNode)
while (!queue.isEmpty()) {
// start with the queue's first node
const node = queue.dequeue()
if (!visited.has(node)) {
// mark the node as visited
visited.add(node)
const neighbors = graph[node]
// put all its neighbors into the queue
for (let i = 0; i < neighbors.length; i++) {
queue.enqueue(neighbors[i])
}
}
}
return visited
}
import Queue from '../Data-Structures/Queue/Queue'
/**
* Breadth-first search is an algorithm for traversing a graph.
*
* It discovers all nodes reachable from the starting position by exploring all of the neighbor nodes at the present
* depth prior to moving on to the nodes at the next depth level.
*
* (description adapted from https://en.wikipedia.org/wiki/Breadth-first_search)
* @see https://www.koderdojo.com/blog/breadth-first-search-and-shortest-path-in-csharp-and-net-core
*/
export function breadthFirstSearch(graph, startingNode) {
// visited keeps track of all nodes visited
const visited = new Set()
// queue contains the nodes to be explored in the future
const queue = new Queue()
queue.enqueue(startingNode)
while (!queue.isEmpty()) {
// start with the queue's first node
const node = queue.dequeue()
if (!visited.has(node)) {
// mark the node as visited
visited.add(node)
const neighbors = graph[node]
// put all its neighbors into the queue
for (let i = 0; i < neighbors.length; i++) {
queue.enqueue(neighbors[i])
}
}
}
return visited
}

View File

@ -1,54 +1,54 @@
import Queue from '../Data-Structures/Queue/Queue'
/**
* Breadth-first approach can be applied to determine the shortest path between two nodes in an equi-weighted graph.
*
* It searches the target node among all neighbors of the starting node, then the process is repeated on the level of
* the neighbors of the neighbors and so on.
*
* @see https://en.wikipedia.org/wiki/Breadth-first_search
* @see https://www.koderdojo.com/blog/breadth-first-search-and-shortest-path-in-csharp-and-net-core
*/
export function breadthFirstShortestPath (graph, startNode, targetNode) {
// check if startNode & targetNode are identical
if (startNode === targetNode) {
return [startNode]
}
// visited keeps track of all nodes visited
const visited = new Set()
// queue contains the paths to be explored in the future
const initialPath = [startNode]
const queue = new Queue()
queue.enqueue(initialPath)
while (!queue.isEmpty()) {
// start with the queue's first path
const path = queue.dequeue()
const node = path[path.length - 1]
// explore this node if it hasn't been visited yet
if (!visited.has(node)) {
// mark the node as visited
visited.add(node)
const neighbors = graph[node]
// create a new path in the queue for each neighbor
for (let i = 0; i < neighbors.length; i++) {
const newPath = path.concat([neighbors[i]])
// the first path to contain the target node is the shortest path
if (neighbors[i] === targetNode) {
return newPath
}
// queue the new path
queue.enqueue(newPath)
}
}
}
// the target node was not reachable
return []
}
import Queue from '../Data-Structures/Queue/Queue'
/**
* Breadth-first approach can be applied to determine the shortest path between two nodes in an equi-weighted graph.
*
* It searches the target node among all neighbors of the starting node, then the process is repeated on the level of
* the neighbors of the neighbors and so on.
*
* @see https://en.wikipedia.org/wiki/Breadth-first_search
* @see https://www.koderdojo.com/blog/breadth-first-search-and-shortest-path-in-csharp-and-net-core
*/
export function breadthFirstShortestPath(graph, startNode, targetNode) {
// check if startNode & targetNode are identical
if (startNode === targetNode) {
return [startNode]
}
// visited keeps track of all nodes visited
const visited = new Set()
// queue contains the paths to be explored in the future
const initialPath = [startNode]
const queue = new Queue()
queue.enqueue(initialPath)
while (!queue.isEmpty()) {
// start with the queue's first path
const path = queue.dequeue()
const node = path[path.length - 1]
// explore this node if it hasn't been visited yet
if (!visited.has(node)) {
// mark the node as visited
visited.add(node)
const neighbors = graph[node]
// create a new path in the queue for each neighbor
for (let i = 0; i < neighbors.length; i++) {
const newPath = path.concat([neighbors[i]])
// the first path to contain the target node is the shortest path
if (neighbors[i] === targetNode) {
return newPath
}
// queue the new path
queue.enqueue(newPath)
}
}
}
// the target node was not reachable
return []
}

View File

@ -1,23 +1,27 @@
class GraphUnweightedUndirectedAdjacencyList {
// Unweighted Undirected Graph class
constructor () {
constructor() {
this.connections = {}
}
addNode (node) {
addNode(node) {
// Function to add a node to the graph (connection represented by set)
this.connections[node] = new Set()
}
addEdge (node1, node2) {
addEdge(node1, node2) {
// Function to add an edge (adds the node too if they are not present in the graph)
if (!(node1 in this.connections)) { this.addNode(node1) }
if (!(node2 in this.connections)) { this.addNode(node2) }
if (!(node1 in this.connections)) {
this.addNode(node1)
}
if (!(node2 in this.connections)) {
this.addNode(node2)
}
this.connections[node1].add(node2)
this.connections[node2].add(node1)
}
DFSComponent (components, node, visited) {
DFSComponent(components, node, visited) {
// Helper function to populate the visited set with the nodes in each component
// adding the first visited node in the component to the array
@ -28,18 +32,22 @@ class GraphUnweightedUndirectedAdjacencyList {
const curr = stack.pop()
visited.add(curr.toString())
for (const neighbour of this.connections[curr].keys()) {
if (!visited.has(neighbour.toString())) { stack.push(neighbour) }
if (!visited.has(neighbour.toString())) {
stack.push(neighbour)
}
}
}
}
connectedComponents () {
connectedComponents() {
// Function to generate the Connected Components
// Result is an array containing 1 node from each component
const visited = new Set()
const components = []
for (const node of Object.keys(this.connections)) {
if (!visited.has(node.toString())) { this.DFSComponent(components, node, visited) }
if (!visited.has(node.toString())) {
this.DFSComponent(components, node, visited)
}
}
return components
}

View File

@ -3,7 +3,7 @@ The density of a network is a measure of how many edges exist proportional to
how many edges would exist in a complete network (where all possible edges).
https://networkx.org/documentation/networkx-1.9/reference/generated/networkx.classes.function.density.html
*/
function density (numberOfNodes, numberOfEdges, isDirected = false) {
function density(numberOfNodes, numberOfEdges, isDirected = false) {
const multi = isDirected ? 1 : 2
return (multi * numberOfEdges) / (numberOfNodes * (numberOfNodes - 1))
}

View File

@ -1,30 +1,36 @@
class GraphUnweightedUndirected {
// Unweighted Undirected Graph class
constructor () {
constructor() {
this.connections = {}
}
addNode (node) {
addNode(node) {
// Function to add a node to the graph (connection represented by set)
this.connections[node] = new Set()
}
addEdge (node1, node2) {
addEdge(node1, node2) {
// Function to add an edge (adds the node too if they are not present in the graph)
if (!(node1 in this.connections)) { this.addNode(node1) }
if (!(node2 in this.connections)) { this.addNode(node2) }
if (!(node1 in this.connections)) {
this.addNode(node1)
}
if (!(node2 in this.connections)) {
this.addNode(node2)
}
this.connections[node1].add(node2)
this.connections[node2].add(node1)
}
DFSIterative (node, value) {
DFSIterative(node, value) {
// DFS Function to search if a node with the given value is present in the graph
const stack = [node]
const visited = new Set()
while (stack.length > 0) {
const currNode = stack.pop()
// if the current node contains the value being searched for, true is returned
if (currNode === value) { return true }
if (currNode === value) {
return true
}
// adding the current node to the visited set
visited.add(currNode)
// adding neighbours in the stack

View File

@ -1,32 +1,40 @@
class GraphUnweightedUndirected {
// Unweighted Undirected Graph class
constructor () {
constructor() {
this.connections = {}
}
addNode (node) {
addNode(node) {
// Function to add a node to the graph (connection represented by set)
this.connections[node] = new Set()
}
addEdge (node1, node2) {
addEdge(node1, node2) {
// Function to add an edge (adds the node too if they are not present in the graph)
if (!(node1 in this.connections)) { this.addNode(node1) }
if (!(node2 in this.connections)) { this.addNode(node2) }
if (!(node1 in this.connections)) {
this.addNode(node1)
}
if (!(node2 in this.connections)) {
this.addNode(node2)
}
this.connections[node1].add(node2)
this.connections[node2].add(node1)
}
DFSRecursive (node, value, visited = new Set()) {
DFSRecursive(node, value, visited = new Set()) {
// DFS Function to search if a node with the given value is present in the graph
// checking if the searching node has been found
if (node === value) { return true }
if (node === value) {
return true
}
// adding the current node to the visited set
visited.add(node)
// calling the helper function recursively for all unvisited nodes
for (const neighbour of this.connections[node]) {
if (!visited.has(neighbour)) {
if (this.DFSRecursive(neighbour, value, visited)) { return true }
if (this.DFSRecursive(neighbour, value, visited)) {
return true
}
}
}
return false

View File

@ -6,7 +6,7 @@
* It uses graph data structure.
*/
function createGraph (V, E) {
function createGraph(V, E) {
// V - Number of vertices in graph
// E - Number of edges in graph (u,v,w)
const adjList = [] // Adjacency list
@ -20,7 +20,7 @@ function createGraph (V, E) {
return adjList
}
function djikstra (graph, V, src) {
function djikstra(graph, V, src) {
const vis = Array(V).fill(0)
const dist = []
for (let i = 0; i < V; i++) dist.push([10000, -1])

View File

@ -1,5 +1,5 @@
// starting at s
function solve (graph, s) {
function solve(graph, s) {
const solutions = {}
solutions[s] = []
solutions[s].dist = 0
@ -10,12 +10,16 @@ function solve (graph, s) {
let dist = Infinity
for (const n in solutions) {
if (!solutions[n]) { continue }
if (!solutions[n]) {
continue
}
const ndist = solutions[n].dist
const adj = graph[n]
for (const a in adj) {
if (solutions[a]) { continue }
if (solutions[a]) {
continue
}
const d = adj[a] + ndist
if (d < dist) {

View File

@ -9,7 +9,7 @@
*/
class Kosaraju {
constructor (graph) {
constructor(graph) {
this.connections = {}
this.reverseConnections = {}
this.stronglyConnectedComponents = []
@ -20,14 +20,14 @@ class Kosaraju {
return this.kosaraju()
}
addNode (node) {
addNode(node) {
// Function to add a node to the graph (connection represented by set)
this.connections[node] = new Set()
this.reverseConnections[node] = new Set()
this.topoSorted = []
}
addEdge (node1, node2) {
addEdge(node1, node2) {
// Function to add an edge (adds the node too if they are not present in the graph)
if (!(node1 in this.connections) || !(node1 in this.reverseConnections)) {
this.addNode(node1)
@ -39,7 +39,7 @@ class Kosaraju {
this.reverseConnections[node2].add(node1)
}
dfsTopoSort (node, visited) {
dfsTopoSort(node, visited) {
visited.add(node)
for (const child of this.connections[node]) {
if (!visited.has(child)) this.dfsTopoSort(child, visited)
@ -47,7 +47,7 @@ class Kosaraju {
this.topoSorted.push(node)
}
topoSort () {
topoSort() {
// Function to perform topological sorting
const visited = new Set()
const nodes = Object.keys(this.connections).map((key) => Number(key))
@ -56,7 +56,7 @@ class Kosaraju {
}
}
dfsKosaraju (node, visited) {
dfsKosaraju(node, visited) {
visited.add(node)
this.stronglyConnectedComponents[
this.stronglyConnectedComponents.length - 1
@ -66,7 +66,7 @@ class Kosaraju {
}
}
kosaraju () {
kosaraju() {
// Function to perform Kosaraju Algorithm
const visited = new Set()
while (this.topoSorted.length > 0) {
@ -80,7 +80,7 @@ class Kosaraju {
}
}
function kosaraju (graph) {
function kosaraju(graph) {
const stronglyConnectedComponents = new Kosaraju(graph)
return stronglyConnectedComponents
}

View File

@ -1,6 +1,6 @@
class DisjointSetTreeNode {
// Disjoint Set Node to store the parent and rank
constructor (key) {
constructor(key) {
this.key = key
this.parent = this
this.rank = 0
@ -9,17 +9,17 @@ class DisjointSetTreeNode {
class DisjointSetTree {
// Disjoint Set DataStructure
constructor () {
constructor() {
// map to from node name to the node object
this.map = {}
}
makeSet (x) {
makeSet(x) {
// Function to create a new set with x as its member
this.map[x] = new DisjointSetTreeNode(x)
}
findSet (x) {
findSet(x) {
// Function to find the set x belongs to (with path-compression)
if (this.map[x] !== this.map[x].parent) {
this.map[x].parent = this.findSet(this.map[x].parent.key)
@ -27,12 +27,12 @@ class DisjointSetTree {
return this.map[x].parent
}
union (x, y) {
union(x, y) {
// Function to merge 2 disjoint sets
this.link(this.findSet(x), this.findSet(y))
}
link (x, y) {
link(x, y) {
// Helper function for union operation
if (x.rank > y.rank) {
y.parent = x
@ -47,26 +47,30 @@ class DisjointSetTree {
class GraphWeightedUndirectedAdjacencyList {
// Weighted Undirected Graph class
constructor () {
constructor() {
this.connections = {}
this.nodes = 0
}
addNode (node) {
addNode(node) {
// Function to add a node to the graph (connection represented by set)
this.connections[node] = {}
this.nodes += 1
}
addEdge (node1, node2, weight) {
addEdge(node1, node2, weight) {
// Function to add an edge (adds the node too if they are not present in the graph)
if (!(node1 in this.connections)) { this.addNode(node1) }
if (!(node2 in this.connections)) { this.addNode(node2) }
if (!(node1 in this.connections)) {
this.addNode(node1)
}
if (!(node2 in this.connections)) {
this.addNode(node2)
}
this.connections[node1][node2] = weight
this.connections[node2][node1] = weight
}
KruskalMST () {
KruskalMST() {
// Kruskal's Algorithm to generate a Minimum Spanning Tree (MST) of a graph
// Details: https://en.wikipedia.org/wiki/Kruskal%27s_algorithm
// getting the edges in ascending order of weights
@ -83,7 +87,7 @@ class GraphWeightedUndirectedAdjacencyList {
edges.sort((a, b) => a[2] - b[2])
// creating the disjoint set
const disjointSet = new DisjointSetTree()
Object.keys(this.connections).forEach(node => disjointSet.makeSet(node))
Object.keys(this.connections).forEach((node) => disjointSet.makeSet(node))
// MST generation
const graph = new GraphWeightedUndirectedAdjacencyList()
let numEdges = 0

View File

@ -9,14 +9,14 @@
import { BinaryLifting } from './BinaryLifting'
class LCABinaryLifting extends BinaryLifting {
constructor (root, tree) {
constructor(root, tree) {
super(root, tree)
this.depth = new Map() // depth[node] stores the depth of node from root
this.depth.set(root, 1)
this.dfsDepth(root, root)
}
dfsDepth (node, parent) {
dfsDepth(node, parent) {
// DFS to find depth of every node in the tree
for (const child of this.connections.get(node)) {
if (child !== parent) {
@ -26,10 +26,10 @@ class LCABinaryLifting extends BinaryLifting {
}
}
getLCA (node1, node2) {
getLCA(node1, node2) {
// We make sure that node1 is the deeper node among node1 and node2
if (this.depth.get(node1) < this.depth.get(node2)) {
[node1, node2] = [node2, node1]
;[node1, node2] = [node2, node1]
}
// We check if node1 is the ancestor of node2, and if so, then return node1
const k = this.depth.get(node1) - this.depth.get(node2)
@ -48,7 +48,7 @@ class LCABinaryLifting extends BinaryLifting {
}
}
function lcaBinaryLifting (root, tree, queries) {
function lcaBinaryLifting(root, tree, queries) {
const graphObject = new LCABinaryLifting(root, tree)
const lowestCommonAncestors = []
for (const [node1, node2] of queries) {

View File

@ -2,11 +2,11 @@
class Graph {
// Generic graph: the algorithm works regardless of direction or weight
constructor () {
constructor() {
this.edges = []
}
addEdge (node1, node2) {
addEdge(node1, node2) {
// Adding edges to the graph
this.edges.push({
node1,
@ -14,15 +14,15 @@ class Graph {
})
}
nodeNeighbors (node) {
nodeNeighbors(node) {
// Returns an array with all of the node neighbors
const neighbors = new Set()
for (const edge of this.edges) {
// Checks if they have an edge between them and if the neighbor is not
// already in the neighbors array
if (edge.node1 === node && !(neighbors.has(edge.node2))) {
if (edge.node1 === node && !neighbors.has(edge.node2)) {
neighbors.add(edge.node2)
} else if (edge.node2 === node && !(neighbors.has(edge.node1))) {
} else if (edge.node2 === node && !neighbors.has(edge.node1)) {
neighbors.add(edge.node1)
}
}

View File

@ -1,24 +1,28 @@
import { KeyPriorityQueue } from '../Data-Structures/Heap/KeyPriorityQueue'
class GraphWeightedUndirectedAdjacencyList {
// Weighted Undirected Graph class
constructor () {
constructor() {
this.connections = {}
}
addNode (node) {
addNode(node) {
// Function to add a node to the graph (connection represented by set)
this.connections[node] = {}
}
addEdge (node1, node2, weight) {
addEdge(node1, node2, weight) {
// Function to add an edge (adds the node too if they are not present in the graph)
if (!(node1 in this.connections)) { this.addNode(node1) }
if (!(node2 in this.connections)) { this.addNode(node2) }
if (!(node1 in this.connections)) {
this.addNode(node1)
}
if (!(node2 in this.connections)) {
this.addNode(node2)
}
this.connections[node1][node2] = weight
this.connections[node2][node1] = weight
}
PrimMST (start) {
PrimMST(start) {
// Prim's Algorithm to generate a Minimum Spanning Tree (MST) of a graph
// Details: https://en.wikipedia.org/wiki/Prim%27s_algorithm
const distance = {}
@ -26,16 +30,21 @@ class GraphWeightedUndirectedAdjacencyList {
const priorityQueue = new KeyPriorityQueue()
// Initialization
for (const node in this.connections) {
distance[node] = (node === start.toString() ? 0 : Infinity)
distance[node] = node === start.toString() ? 0 : Infinity
parent[node] = null
priorityQueue.push(node, distance[node])
}
// Updating 'distance' object
while (!priorityQueue.isEmpty()) {
const node = priorityQueue.pop()
Object.keys(this.connections[node]).forEach(neighbour => {
if (priorityQueue.contains(neighbour) && distance[node] + this.connections[node][neighbour] < distance[neighbour]) {
distance[neighbour] = distance[node] + this.connections[node][neighbour]
Object.keys(this.connections[node]).forEach((neighbour) => {
if (
priorityQueue.contains(neighbour) &&
distance[node] + this.connections[node][neighbour] <
distance[neighbour]
) {
distance[neighbour] =
distance[node] + this.connections[node][neighbour]
parent[neighbour] = node
priorityQueue.update(neighbour, distance[neighbour])
}
@ -44,7 +53,7 @@ class GraphWeightedUndirectedAdjacencyList {
// MST Generation from the 'parent' object
const graph = new GraphWeightedUndirectedAdjacencyList()
Object.keys(parent).forEach(node => {
Object.keys(parent).forEach((node) => {
if (node && parent[node]) {
graph.addEdge(node, parent[node], this.connections[node][parent[node]])
}

View File

@ -4,10 +4,16 @@ test('Test Case 1', () => {
const V = 5
const E = 8
const destination = 3
const graph = [[0, 1, -1], [0, 2, 4],
[1, 2, 3], [1, 3, 2],
[1, 4, 2], [3, 2, 5],
[3, 1, 1], [4, 3, -3]]
const graph = [
[0, 1, -1],
[0, 2, 4],
[1, 2, 3],
[1, 3, 2],
[1, 4, 2],
[3, 2, 5],
[3, 1, 1],
[4, 3, -3]
]
const dist = BellmanFord(graph, V, E, 0, destination)
expect(dist).toBe(-2)
})
@ -15,10 +21,17 @@ test('Test Case 2', () => {
const V = 6
const E = 9
const destination = 4
const graph = [[0, 1, 3], [0, 3, 6],
[0, 5, -1], [1, 2, -3],
[1, 4, -2], [5, 2, 5],
[2, 3, 1], [4, 3, 5], [5, 4, 2]]
const graph = [
[0, 1, 3],
[0, 3, 6],
[0, 5, -1],
[1, 2, -3],
[1, 4, -2],
[5, 2, 5],
[2, 3, 1],
[4, 3, 5],
[5, 4, 2]
]
const dist = BellmanFord(graph, V, E, 0, destination)
expect(dist).toBe(1)
})
@ -26,9 +39,13 @@ test('Test Case 3', () => {
const V = 4
const E = 5
const destination = 1
const graph = [[0, 3, -1], [0, 2, 4],
[3, 2, 2], [3, 1, 5],
[2, 1, -1]]
const graph = [
[0, 3, -1],
[0, 2, 4],
[3, 2, 2],
[3, 1, 5],
[2, 1, -1]
]
const dist = BellmanFord(graph, V, E, 0, destination)
expect(dist).toBe(0)
})

View File

@ -21,8 +21,19 @@ describe('BreadthFirstSearch', () => {
*/
it('should return the visited nodes', () => {
expect(Array.from(breadthFirstSearch(graph, 'C'))).toEqual(['C', 'D', 'A', 'B', 'E'])
expect(Array.from(breadthFirstSearch(graph, 'A'))).toEqual(['A', 'B', 'D', 'E'])
expect(Array.from(breadthFirstSearch(graph, 'C'))).toEqual([
'C',
'D',
'A',
'B',
'E'
])
expect(Array.from(breadthFirstSearch(graph, 'A'))).toEqual([
'A',
'B',
'D',
'E'
])
expect(Array.from(breadthFirstSearch(graph, 'F'))).toEqual(['F', 'G'])
})
})

View File

@ -21,8 +21,19 @@ describe('BreadthFirstShortestPath', () => {
*/
it('should return the visited nodes', () => {
expect(breadthFirstShortestPath(graph, 'C', 'E')).toEqual(['C', 'D', 'A', 'B', 'E'])
expect(breadthFirstShortestPath(graph, 'E', 'B')).toEqual(['E', 'D', 'A', 'B'])
expect(breadthFirstShortestPath(graph, 'C', 'E')).toEqual([
'C',
'D',
'A',
'B',
'E'
])
expect(breadthFirstShortestPath(graph, 'E', 'B')).toEqual([
'E',
'D',
'A',
'B'
])
expect(breadthFirstShortestPath(graph, 'F', 'G')).toEqual(['F', 'G'])
expect(breadthFirstShortestPath(graph, 'A', 'G')).toEqual([])
})