二叉树遍历中出现了意外的输出。

huangapple go评论73阅读模式
英文:

unexpected output in binary tree traversal

问题

func New(k int) *Tree
// New() 返回一个随机的二叉树,其中包含值 k, 2k, ..., 10k.

我只是尝试在 goroutine 中遍历二叉树并将值添加到通道中,然后在主 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

英文:
func New(k int) *Tree
// New() returns a random binary tree holding the values k, 2k, ..., 10k.

I'm just trying traversal binary tree in goroutine and add values to channel. Then print them in main goroutine

Code

func binary(t *tree.Tree, ch chan int) {
	if t != nil {
		binary(t.Left, ch)
		ch &lt;- 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(&quot;%d &quot;, &lt;-ch)
		_ = i
	}
}

Expected output = 1 2 3 4 5 6 7 8 9 10

Result = 2 4 6 8 10

答案1

得分: 3

for语句中的range子句用于从通道中接收值并将其存储在循环变量中。

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

然而,你没有使用i,而且你确实从ch接收。所以你会跳过每个第二个元素(如果通道上传递的元素数量为奇数,你还有可能被阻塞)。

请按照以下方式修改代码:

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

The for statement with a range clause over a channel receives values from the channel and stores them in the loop variable.

Meaning the i variable will hold values received from ch, you do not need to receive from ch.

Yet, you're not using i, and you do receive from ch. So you'll skip every second element (and you'll also risk getting blocked if there are odd number of elements delivered on the channel).

Do it like this:

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

答案2

得分: -1

根据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)
    }
}
英文:

Based on the suggestion of icza:

func binary(t *tree.Tree, ch chan int) {
    if t != nil {
        binary(t.Left, ch)
        ch &lt;- 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(&quot;%d &quot;, v)
    }
}

huangapple
  • 本文由 发表于 2021年7月7日 18:49:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/68284627.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定