1. // A Tree is a binary tree with integer values.
    2. type Tree struct {
    3. Left *Tree
    4. Value int
    5. Right *Tree
    6. }
    7. // New returns a new, random binary tree holding the values k, 2k, ..., 10k.
    8. func New(k int) *Tree {
    9. var t *Tree
    10. for _, v := range rand.Perm(10) {
    11. t = insert(t, (1+v)*k)
    12. }
    13. return t
    14. }
    15. func insert(t *Tree, v int) *Tree {
    16. if t == nil {
    17. return &Tree{nil, v, nil}
    18. }
    19. if v < t.Value {
    20. t.Left = insert(t.Left, v)
    21. } else {
    22. t.Right = insert(t.Right, v)
    23. }
    24. return t
    25. }
    26. func (t *Tree) String() string {
    27. if t == nil {
    28. return "()"
    29. }
    30. s := ""
    31. if t.Left != nil {
    32. s += t.Left.String() + " "
    33. }
    34. s += fmt.Sprint(t.Value)
    35. if t.Right != nil {
    36. s += " " + t.Right.String()
    37. }
    38. return "(" + s + ")"
    39. }

    以上代码实现了二叉树的基本功能。下面我们来实现二叉树的比较。

    要比较两个二叉树是否一致。我们建立一个函数:Same(t1, t2 Tree) bool。为了比较二叉树,必需把二叉树的值放进一个通道中。共使用两个通道来进行比较。放入通道中的函数我们建立为Walk(t Tree, ch chan int)同时再建立一个递归函数,用来遍历二叉树所有的叶子节点rangeTree(t *Tree, ch chan int)

    1. //遍历二叉树,把当前节点值传入通道
    2. func rangeTree(t *Tree, ch chan int) {
    3. if t != nil{
    4. rangeTree(t.Left, ch)
    5. ch <- t.Value
    6. rangeTree(t.Right, ch)
    7. }
    8. }
    9. // Walk 步进 tree t 将所有的值从 tree 发送到 channel ch。
    10. func Walk(t *Tree, ch chan int){
    11. rangeTree(t, ch)
    12. close(ch)
    13. }
    14. // Same 检测树 t1 和 t2 是否含有相同的值。
    15. func Same(t1, t2 *Tree) bool{
    16. //建立两个通道
    17. ch1 := make(chan int)
    18. ch2 := make(chan int)
    19. //遍历两个二叉树,把值传入各自的通道
    20. go Walk(t1, ch1)
    21. go Walk(t2, ch2)
    22. //遍历通道进行比较,有不同的值就返回false
    23. for i := range ch1{
    24. if i != <- ch2{
    25. return false
    26. }
    27. }
    28. return true
    29. }

    然后在 main 函数中比较两个 tree

    1. fmt.Println(Same(New(1), New(1)))
    2. fmt.Println(Same(New(1), New(2)))

    完整代码示例

    1. package main
    2. import (
    3. "fmt"
    4. "math/rand"
    5. )
    6. // A Tree is a binary tree with integer values.
    7. type Tree struct {
    8. Left *Tree
    9. Value int
    10. Right *Tree
    11. }
    12. // New returns a new, random binary tree holding the values k, 2k, ..., 10k.
    13. func New(k int) *Tree {
    14. var t *Tree
    15. for _, v := range rand.Perm(10) {
    16. t = insert(t, (1+v)*k)
    17. }
    18. return t
    19. }
    20. func insert(t *Tree, v int) *Tree {
    21. if t == nil {
    22. return &Tree{nil, v, nil}
    23. }
    24. if v < t.Value {
    25. t.Left = insert(t.Left, v)
    26. } else {
    27. t.Right = insert(t.Right, v)
    28. }
    29. return t
    30. }
    31. func (t *Tree) String() string {
    32. if t == nil {
    33. return "()"
    34. }
    35. s := ""
    36. if t.Left != nil {
    37. s += t.Left.String() + " "
    38. }
    39. s += fmt.Sprint(t.Value)
    40. if t.Right != nil {
    41. s += " " + t.Right.String()
    42. }
    43. return "(" + s + ")"
    44. }
    45. // Walk 步进 tree t 将所有的值从 tree 发送到 channel ch。
    46. func Walk(t *Tree, ch chan int){
    47. rangeTree(t, ch)
    48. close(ch)
    49. }
    50. //遍历二叉树,把当前节点值传入通道
    51. func rangeTree(t *Tree, ch chan int) {
    52. if t != nil{
    53. rangeTree(t.Left, ch)
    54. ch <- t.Value
    55. rangeTree(t.Right, ch)
    56. }
    57. }
    58. // Same 检测树 t1 和 t2 是否含有相同的值。
    59. func Same(t1, t2 *Tree) bool{
    60. //建立两个通道
    61. ch1 := make(chan int)
    62. ch2 := make(chan int)
    63. //遍历两个二叉树,把值传入各自的通道
    64. go Walk(t1, ch1)
    65. go Walk(t2, ch2)
    66. //遍历通道进行比较,有不同的值就返回false
    67. for i := range ch1{
    68. if i != <- ch2{
    69. return false
    70. }
    71. }
    72. return true
    73. }
    74. func main() {
    75. fmt.Println("二叉树遍历比较")
    76. fmt.Println("打印 New(1)的值")
    77. //打印 New(1)的值
    78. var ch1 = make(chan int)
    79. go Walk(New(1), ch1)
    80. for v := range ch1{
    81. fmt.Println(v)
    82. }
    83. fmt.Println("打印 New(2)的值")
    84. //打印 New(2)的值
    85. var ch2 = make(chan int)
    86. go Walk(New(2), ch2)
    87. for v := range ch2{
    88. fmt.Println(v)
    89. }
    90. //比较两个tree的值是否相等
    91. fmt.Println(Same(New(1), New(1)))
    92. fmt.Println(Same(New(1), New(2)))
    93. }

    运行结果:

    1. 二叉树遍历比较
    2. 打印 New(1)的值
    3. 1
    4. 2
    5. 3
    6. 4
    7. 5
    8. 6
    9. 7
    10. 8
    11. 9
    12. 10
    13. 打印 New(2)的值
    14. 2
    15. 4
    16. 6
    17. 8
    18. 10
    19. 12
    20. 14
    21. 16
    22. 18
    23. 20
    24. true
    25. false

    golang 等价二叉树 - 图1