《Eloquent JavaScript》第7章buildGraph函数工作原理解析求助
解析《Eloquent JavaScript》中的buildGraph函数
嘿,我完全懂你看这段代码时的困惑——当初我第一次翻到《Eloquent JavaScript》这段的时候也卡了一会儿!让我一步步给你拆解这个buildGraph函数,把每个部分讲明白:
先明确函数的核心目的
这个函数是把双向道路的字符串列表转换成一个邻接表(一种表示图的数据结构),简单说就是让我们能快速查到「从某个地点出发,能直接去哪些地方」。
逐行拆解buildGraph函数
1. 创建空图对象
let graph = Object.create(null);
这里用Object.create(null)创建了一个完全空的对象(没有继承Object.prototype的任何属性,比如toString),这样我们操作这个对象时不会有意外的干扰,比直接用{}更干净。
2. 内部辅助函数addEdge:添加单向路径
这是你最困惑的部分,咱们仔细说:
function addEdge(from, to) { if (graph[from] == null) { graph[from] = [to]; // 为什么是数组? } else { graph[from].push(to); } }
- 这个函数的作用是:在图里添加一条「从
from到to」的单向连接。 - 为什么用数组存
to?因为一个地点可能有多个可达目的地,比如Alice的家能去Bob家、小木屋、邮局,如果直接赋值单个to,后面添加的新目的地会把之前的覆盖掉。用数组就能把所有可达地点都存起来,不会丢失信息。 - 逻辑分支:
- 如果
graph[from]是null,说明这个地点还没有任何记录,所以我们初始化它为一个包含to的数组。 - 如果
graph[from]已经存在(是一个数组),就把新的目的地to追加到数组里。
- 如果
3. 遍历所有道路,添加双向连接
for (let [from, to] of edges.map(r => r.split("-"))) { addEdge(from, to); addEdge(to, from); }
- 第一步:
edges.map(r => r.split("-"))把每个道路字符串拆成两个地点的数组,比如"Alice's House-Bob's House"会变成["Alice's House", "Bob's House"]。 - 第二步:用解构赋值
[from, to]拿到拆分后的两个地点。 - 第三步:调用两次
addEdge——因为道路是双向的!从Alice家能到Bob家,反过来Bob家也能到Alice家,所以要同时添加两条单向路径,保证图的双向可达性。
4. 返回最终的图结构
return graph;
最终得到的roadGraph就是一个实用的查询对象,比如你访问roadGraph["Bob's House"],会得到["Alice's House", "Town Hall"],完美实现了「快速查询某个地点的可达点」的需求。
内容的提问来源于stack exchange,提问作者Meng
相关产品推荐
相关产品推荐

