等价二叉查找树

南楼画角 提交于 2019-12-23 03:54:28

练习:等价二叉查找树

  1. 实现 Walk 函数。
  2. 测试 Walk 函数。
    函数 tree.New(k) 用于构造一个随机结构的已排序二叉查找树,它保存了值 k, 2k, 3k, …, 10k。
    创建一个新的信道 ch 并且对其进行步进:
    go Walk(tree.New(1), ch)
    然后从信道中读取并打印 10 个值。应当是数字 1, 2, 3, …, 10。
  3. 用 Walk 实现 Same 函数来检测 t1 和 t2 是否存储了相同的值。
  4. 测试 Same 函数。
    Same(tree.New(1), tree.New(1)) 应当返回 true,而 Same(tree.New(1), tree.New(2)) 应当返回 false。
    Tree 的文档可在这里找到。
package main

import (
	"fmt"

	"golang.org/x/tour/tree"
)

// Walk 步进 tree t 将所有的值从 tree 发送到 channel ch。
func Walk(t *tree.Tree, ch chan int) {
	// 递归到最左端
	if nil != t.Left {
		Walk(t.Left, ch)
	}

	// L > R
	// 步进读取R
	ch <- t.Value
	if nil != t.Right {
		Walk(t.Right, ch)
	}
}

// Same 检测树 t1 和 t2 是否含有相同的值。
func Same(t1, t2 *tree.Tree) bool {
	
	c1, c2 := make(chan int), make(chan int)
	go Walk(t1, c1)
	go Walk(t2, c2)

	for i := 0; i < 10; i++ {
		// 阻塞循环
		if <-c1 != <-c2 {
			return false
		}
	}
	return true
}

func main() {
	t1 := tree.New(1)
	t2 := tree.New(2)
	fmt.Println(Same(t1, t2))
}

理解难点:

对多线程协同工作使用不多的我, 很难理解chan+goroutine的工作方式, 下面是个人的理解方式(转换成普通容器, 在一个线程中运行):

  • chan看作一个普通容器, 那么 Walk(t1, c1) 会将 tree 中的所有数据从左至右依次写入c1容器中
  • for循环依次从c1容器中读取每个元素

还原 go Walk(t1, c1) 后有点类似于电梯(货物运输工具), 如论有没有电梯存在, 1L 和 2L车间都需要工作

  • <-c1: 2L车间的工作需要1L车间加工后的原材料.
  • c1<-t.Value:1L车间装货, 能装多少取决于电梯的容量(带缓冲区信道)

现实中运输工具速度的概念, 而程序中这个值可以忽略不计.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!