// A Tree is a binary tree with integer values.type Tree struct {Left *TreeValue intRight *Tree}// New returns a new, random binary tree holding the values k, 2k, ..., 10k.func New(k int) *Tree {var t *Treefor _, v := range rand.Perm(10) {t = insert(t, (1+v)*k)}return t}func insert(t *Tree, v int) *Tree {if t == nil {return &Tree{nil, v, nil}}if v < t.Value {t.Left = insert(t.Left, v)} else {t.Right = insert(t.Right, v)}return t}func (t *Tree) String() string {if t == nil {return "()"}s := ""if t.Left != nil {s += t.Left.String() + " "}s += fmt.Sprint(t.Value)if t.Right != nil {s += " " + t.Right.String()}return "(" + s + ")"}
以上代码实现了二叉树的基本功能。下面我们来实现二叉树的比较。
要比较两个二叉树是否一致。我们建立一个函数:Same(t1, t2 Tree) bool。为了比较二叉树,必需把二叉树的值放进一个通道中。共使用两个通道来进行比较。放入通道中的函数我们建立为Walk(t Tree, ch chan int)同时再建立一个递归函数,用来遍历二叉树所有的叶子节点rangeTree(t *Tree, ch chan int)
//遍历二叉树,把当前节点值传入通道func rangeTree(t *Tree, ch chan int) {if t != nil{rangeTree(t.Left, ch)ch <- t.ValuerangeTree(t.Right, ch)}}// Walk 步进 tree t 将所有的值从 tree 发送到 channel ch。func Walk(t *Tree, ch chan int){rangeTree(t, ch)close(ch)}// Same 检测树 t1 和 t2 是否含有相同的值。func Same(t1, t2 *Tree) bool{//建立两个通道ch1 := make(chan int)ch2 := make(chan int)//遍历两个二叉树,把值传入各自的通道go Walk(t1, ch1)go Walk(t2, ch2)//遍历通道进行比较,有不同的值就返回falsefor i := range ch1{if i != <- ch2{return false}}return true}
然后在 main 函数中比较两个 tree
fmt.Println(Same(New(1), New(1)))fmt.Println(Same(New(1), New(2)))
完整代码示例
package mainimport ("fmt""math/rand")// A Tree is a binary tree with integer values.type Tree struct {Left *TreeValue intRight *Tree}// New returns a new, random binary tree holding the values k, 2k, ..., 10k.func New(k int) *Tree {var t *Treefor _, v := range rand.Perm(10) {t = insert(t, (1+v)*k)}return t}func insert(t *Tree, v int) *Tree {if t == nil {return &Tree{nil, v, nil}}if v < t.Value {t.Left = insert(t.Left, v)} else {t.Right = insert(t.Right, v)}return t}func (t *Tree) String() string {if t == nil {return "()"}s := ""if t.Left != nil {s += t.Left.String() + " "}s += fmt.Sprint(t.Value)if t.Right != nil {s += " " + t.Right.String()}return "(" + s + ")"}// Walk 步进 tree t 将所有的值从 tree 发送到 channel ch。func Walk(t *Tree, ch chan int){rangeTree(t, ch)close(ch)}//遍历二叉树,把当前节点值传入通道func rangeTree(t *Tree, ch chan int) {if t != nil{rangeTree(t.Left, ch)ch <- t.ValuerangeTree(t.Right, ch)}}// Same 检测树 t1 和 t2 是否含有相同的值。func Same(t1, t2 *Tree) bool{//建立两个通道ch1 := make(chan int)ch2 := make(chan int)//遍历两个二叉树,把值传入各自的通道go Walk(t1, ch1)go Walk(t2, ch2)//遍历通道进行比较,有不同的值就返回falsefor i := range ch1{if i != <- ch2{return false}}return true}func main() {fmt.Println("二叉树遍历比较")fmt.Println("打印 New(1)的值")//打印 New(1)的值var ch1 = make(chan int)go Walk(New(1), ch1)for v := range ch1{fmt.Println(v)}fmt.Println("打印 New(2)的值")//打印 New(2)的值var ch2 = make(chan int)go Walk(New(2), ch2)for v := range ch2{fmt.Println(v)}//比较两个tree的值是否相等fmt.Println(Same(New(1), New(1)))fmt.Println(Same(New(1), New(2)))}
运行结果:
二叉树遍历比较打印 New(1)的值12345678910打印 New(2)的值2468101214161820truefalse

