【发布时间】:2022-11-16 06:42:56
【问题描述】:
我用 JavaScript 拼凑了这种拓扑排序,并有一个基于 this post 的图表:
const graph = {
edges: {
c: ['d', 'f'],
d: ['e'],
f: ['e'],
a: ['b', 'c'],
b: ['d', 'e'],
}
}
// Calcuate the incoming degree of each vertex
const vertices = Object.keys(graph.edges)
const inDegree = {}
for (const v of vertices) {
const neighbors = graph.edges[v]
neighbors?.forEach(neighbor => {
inDegree[neighbor] = inDegree[neighbor] + 1 || 1
})
}
const queue = vertices.filter((v) => !inDegree[v])
const list = []
while (queue.length) {
const v = queue.shift()
const neighbors = graph.edges[v]
list.push(v)
// adjust the incoming degree of its neighbors
neighbors?.forEach(neighbor => {
inDegree[neighbor]--
if (inDegree[neighbor] === 0) {
queue.push(neighbor)
}
})
}
console.log(list)
99% 确定这是 JS 中拓扑排序的正确实现。
我有兴趣进行热模块重新加载,并且有兴趣模拟更新模块图中的相关节点。所以说d更新了。然后我们不关心a、b或c,它们很好,我们只关心更新d和未来的节点然后是e,顺序是[ d, e ]。我们不关心 f,因为它不与 d 内联。
我如何更新此topsort函数以获取一个键(顶点/节点),并从那时起,包括元素,所以如果我通过d,我得到[ d, e ]?
是像 list.slice(list.indexOf('d')) 一样简单,还是通用/稳健的解决方案更棘手?
我不认为这是正确的,因为如果我为模块 b 这样做,我们应该只需要更新 [ b, d, e ],但我的解决方案包括 c,这是不正确的。不知道如何解决这个问题。
【问题讨论】:
-
如果
d更改并且结果包括[d,f,e],其中包括f因为它提供e,那么看起来如果更新b,则 [b,c,d,f,e]`应该是解决方案,因为b和c都提供d,不是吗? -
@Trentium btilly 说的对,应该是
[ 'b', 'd', 'e' ]。 -
然后
d的变化导致[d, e]而不是[d,f,e],对吗? -
是的,你是对的!哈,混乱。更新。
标签: javascript algorithm sorting graph topological-sort