【问题标题】:unexpected output in binary tree traversal二叉树遍历中的意外输出
【发布时间】:2021-09-17 22:00:06
【问题描述】:
func New(k int) *Tree
// New() returns a random binary tree holding the values k, 2k, ..., 10k.

我只是在 goroutine 中尝试遍历二叉树并向通道添加值。然后在 main goroutine 中打印它们

代码

func binary(t *tree.Tree, ch chan int) {
    if t != nil {
        binary(t.Left, ch)
        ch <- t.Value
        binary(t.Right, ch)
    }
}

func Walk(t *tree.Tree, ch chan int) {
    defer close(ch)
    binary(t, ch)
}

func main() {
    ch := make(chan int)
    go Walk(tree.New(1), ch)
    for i := range ch {
        fmt.Printf("%d ", <-ch)
        _ = i
    }
}

预期输出 = 1 2 3 4 5 6 7 8 9 10

结果 = 2 4 6 8 10

【问题讨论】:

    标签: go concurrency channel


    【解决方案1】:

    带有range 子句的for 语句在通道上接收来自通道的值并将它们存储在循环变量中。

    意味着i 变量将保存从ch 接收的值,您不需要从ch 接收。

    然而,您没有使用i,而是收到了来自ch 的信息。因此,您将跳过每个第二个元素(如果频道上传递的元素数量为奇数,您也将面临被阻止的风险)。

    这样做:

    for v := range ch {
        fmt.Printf("%d ", v)
    }
    

    【讨论】:

      【解决方案2】:

      根据icza的建议:

      func binary(t *tree.Tree, ch chan int) {
          if t != nil {
              binary(t.Left, ch)
              ch <- t.Value
              binary(t.Right, ch)
          }
      }
      
      func Walk(t *tree.Tree, ch chan int) {
          defer close(ch)
          binary(t, ch)
      }
      
      func main() {
          ch := make(chan int)
          go Walk(tree.New(1), ch)
          for v := range ch {
          fmt.Printf("%d ", v)
          }
      }
      

      【讨论】:

      • 拒绝投票,因为这只是重新包装现有答案(没有解释),因此没有用。
      猜你喜欢
      • 1970-01-01
      • 2012-11-09
      • 1970-01-01
      • 2012-01-01
      • 2022-11-11
      • 2016-02-03
      • 1970-01-01
      • 2021-11-20
      相关资源
      最近更新 更多