【发布时间】:2020-11-17 16:27:27
【问题描述】:
有没有合适的方法在 Go 中的递归树搜索中实现并发?
以下代码显示了对具有 id 和 children 属性的节点树的基本递归树搜索。 如果我找到结果我可以关闭频道但如果没有结果如何处理?
// Node is a struct containing int field ID and []*Node field Children.
type Node struct {
ID int
Children []*Node
}
// Find search for a record by id inside an array of records
func Find(node *Node, id int) *Node {
if node.ID == id {
return node
}
for _, c := range node.Children {
found := Find(c, id)
if found != nil {
return found
}
}
return nil
}
【问题讨论】:
-
是的,你的实现会为你的树的每个分支启动一个 goroutine,因此如果它进入一个不包含值的分支,它将浏览它直到结束。此外,写一个封闭的通道是一个错误。另外,生成那么多 goroutine 效率不高。在您的伪代码中,您正在关闭通道以表示找到了一个值。如果值存在两次会发生什么?找到值是否一定意味着您已经结束浏览树?
-
这不是一个小问题,也就是说,我相信这是您没有得到帮助的原因之一。拥有多个 goroutine 在某些情况下可以提高算法的速度,但在其他情况下可能会有害。生成的例程越多,对运行时处理上下文切换施加的压力就越大,go 肯定能够并行处理数以百万计的例程,但它是有代价的。您必须始终权衡成本和收益。在您的伪代码中生成一个例程来执行比较并不好。
-
想想你的问题我的一些问题是,如何检测搜索结束,如何对树进行分区,如何防止在某些边缘情况下出现愚蠢的性能陷阱,总的来说,它真的值得吗?非并发编程执行起来非常快速高效。
-
Is there a possible way to do it?。是的。很多种方法。总是赢吗?这么简单的数据结构能做到吗?不太清楚。 -
我强烈建议您搜索、查看和学习围棋作者和专业人士提供的许多在线会议,以便在继续之前了解更多信息。
标签: go recursion concurrency