You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

《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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:14:02