gpt4 book ai didi

go - 等效二叉树练习,实现 "concurrency"

转载 作者:行者123 更新时间:2023-12-03 17:23:25 28 4
gpt4 key购买 nike

我正在解决围棋之旅中的练习,Equivalent Binary Tree .
这个练习需要一个人来实现一个 Walk该函数应该遍历一棵树并将所有值从树中有序地发送到一个 channel 。
演练声明指出:

... We'll use Go's concurrency and channels to write a simple solution.


阅读该行,我认为实现 Walk 具有挑战性。以某种方式为每个左/右子树启动一个 goroutine 并启用 Walk比非并发版本运行得更快(关于时间复杂度)。让我用代码更详细地解释一下。
这是我的早期代码 Walk :
func Walk(t *tree.Tree, ch chan int) {
defer close(ch)
if t == nil { return }

lch, rch := make(chan int), make(chan int)
go Walk(t.Left, lch)
for v := range lch { ch <- v }

ch <- t.Value

go Walk(t.Right, rch)
for v := range rch { ch <- v }

return
}
它确实使用了 goroutines,但实际上与不使用 goroutines 的遍历没有区别,因为 ealry for v := range lch { ... }延迟 go Walk(t.Right, rch)直到结束。
向上移动没有任何区别 go Walk(t.Right, rch) :
func Walk(t *tree.Tree, ch chan int) {
defer close(ch)
if t == nil { return }

lch, rch := make(chan int), make(chan int)
go Walk(t.Left, lch)
go Walk(t.Right, rch)

for v := range lch { ch <- v }
ch <- t.Value
for v := range rch { ch <- v }
}
a tree with colored nodes go Walk(t.Left, lch)沿着整个左子树(以蓝色为根)和从 lch 发送的值走立即收到。 go Walk(t.Right, rch)也试图走,但被阻止为 ch <- t.Value在右子树的最左边的节点(红色)上这样做并传播阻塞。这种状态一直持续到 for v := range rch { ch <- v }到达了。
我的问题 :
如何实现 Walk以某种方式使 goroutine(对应于左或右)避免被 ch <- t.Value 阻塞越多越好?

最佳答案

来自右子树的值需要缓冲区(例如缓冲 channel ),因为它们必须持续存在,直到消耗掉这些值之前的值( <-lcht.Value )。
为大小未知的子树准备缓冲区有几个含义

  • 如果是缓冲 channel ,make(chan int, N) , 被使用,选择 N很关键。如 N碰巧对于子树来说太小了,子树的 goroutine 块太快了。如果它太大,内存会被不必要地浪费。
  • 使用自动调整缓冲区大小来实现自定义 channel 可能是一种解决方案,但它会引入额外的复杂性和开销。我不知道惩罚是否抵消了性能提升。这取决于自定义 channel 如何管理其内部缓冲区或如何管理这些缓冲区。

  • 在我看来, 没有简单通用的解决方案对于这种问题,“遍历一个随机的、并发挤出的未知树”。

    关于go - 等效二叉树练习,实现 "concurrency",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64468668/

    28 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com