-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtree_walker.go
72 lines (56 loc) · 1.56 KB
/
tree_walker.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
package main
import (
"code.google.com/p/go-tour/tree"
"fmt"
)
// Walker walks the tree t sending all values
// from the tree to the channel ch.
func Walker(t *tree.Tree, ch chan int) {
if t == nil {
return
}
Walker(t.Left, ch)
ch <- t.Value
Walker(t.Right, ch)
}
// The TreeWalker orchestrates the walking of the tree
// and returns a read-only channel for comparison later.
func TreeWalker(t *tree.Tree) <-chan int {
// We make the channel writable at first
ch := make(chan int)
// Kick off the walker in its own goroutine.
// Close the channel once we're done walking it.
go func() {
Walker(t, ch)
close(ch)
}()
// This casts the channel to a read-only channel
return ch
}
// Same determines whether the trees
// t1 and t2 contain the same values.
func Same(t1, t2 *tree.Tree) bool {
// Create two TreeWalker channels to receive values on
c1, c2 := TreeWalker(t1), TreeWalker(t2)
for {
// This is a two value form of recieving from a channel.
// The _ok values are false when all values have been received
// from the channel and the channel is closed.
left, left_ok := <-c1
right, right_ok := <-c2
if !left_ok || !right_ok {
// If one of the channels have been closed, compare
return left_ok == right_ok
}
if left != right {
// Just exit out of the for loop if either of the incoming
// values don't match.
break
}
}
return false
}
func main() {
fmt.Printf("tree.New(1) same as tree.New(1)? %v\n\n", Same(tree.New(1), tree.New(1)))
fmt.Printf("tree.New(1) same as tree.New(2)? %v\n\n", Same(tree.New(1), tree.New(2)))
}