-
Notifications
You must be signed in to change notification settings - Fork 11
Expand file tree
/
Copy pathbfs.ts
More file actions
57 lines (49 loc) · 1.3 KB
/
bfs.ts
File metadata and controls
57 lines (49 loc) · 1.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
import type { CodeGraph } from '../model.js';
export interface BfsOpts {
maxDepth?: number;
direction?: 'forward' | 'backward' | 'both';
}
/**
* Breadth-first traversal on a CodeGraph.
*
* @returns nodeId → depth from nearest start node
*/
export function bfs(
graph: CodeGraph,
startIds: string | string[],
opts: BfsOpts = {},
): Map<string, number> {
const maxDepth = opts.maxDepth ?? Infinity;
const direction = opts.direction ?? 'forward';
const starts = Array.isArray(startIds) ? startIds : [startIds];
const depths = new Map<string, number>();
const queue: string[] = [];
for (const id of starts) {
const key = String(id);
if (graph.hasNode(key)) {
depths.set(key, 0);
queue.push(key);
}
}
let head = 0;
while (head < queue.length) {
const current = queue[head++]!;
const depth = depths.get(current)!;
if (depth >= maxDepth) continue;
let neighbors: string[];
if (direction === 'forward') {
neighbors = graph.successors(current);
} else if (direction === 'backward') {
neighbors = graph.predecessors(current);
} else {
neighbors = graph.neighbors(current);
}
for (const n of neighbors) {
if (!depths.has(n)) {
depths.set(n, depth + 1);
queue.push(n);
}
}
}
return depths;
}