Go语言并发比较二叉树(Binary Tree)

        二叉树是一种很常见的数据结构,每个节点拥有左子树与右子树,且最多有两个子节点的一种数据结构,因为很多实际问题都可以抽象成二叉树,所以这种结构还是很重要的

上一篇我们通过学习了 Go语言进阶,闭包、指针、并发 中的并发,现在来通过各自的goroutine来比较一对二叉树,巩固在Go中并发的应用。

//Go语言的并发原语使得并发概念变得简单,示例:比较二叉树
// 不同形状的树,但内容相同,比如:
//
//         4                 6
//      2     6            4   7
//    1   3 5  7         2    5
//                     1  3
//

package main

import (
	"fmt"
	"math/rand"
)

// 定义一个二叉树结构(整数值)
type Tree struct {
	Left  *Tree
	Value int
	Right *Tree
}

// 递归遍历树的各个子节点,然后将值发送到通道ch
func Walk(t *Tree, ch chan int) {
	// 判断是否是空节点
	if t == nil {
		return
	}
	Walk(t.Left, ch)
	ch <- t.Value
	Walk(t.Right, ch)
}

// 创建新的通道,goroutine启动Walk,然后返回一个只读的值的通道
// 使用了匿名函数,go func()
func Walker(t *Tree) <-chan int {
	ch := make(chan int)
	go func() {
		Walk(t, ch)
		//fmt.Println(t)
		close(ch)
	}()
	return ch
}

// 比较同时运行的两个Walker返回的值,如果内容相同就返回true
func Compare(t1, t2 *Tree) bool {
	c1, c2 := Walker(t1), Walker(t2)
	for {
		v1, ok1 := <-c1
		v2, ok2 := <-c2
		//fmt.Println(<-c1, <-c2)
		if !ok1 || !ok2 {
			return ok1 == ok2
		}
		if v1 != v2 {
			break
		}
	}
	return false
}

// 生成一个新的随机二叉树,rand.Perm随机打乱数组中的值
func New(n, k int) *Tree {
	var t *Tree
	for _, v := range rand.Perm(n) {
		t = insert(t, (1+v)*k)
	}
	return t
}

func insert(t *Tree, v int) *Tree {
	//空二叉树,就将插入的节点v当作根节点
	if t == nil {
		return &Tree{nil, v, nil}
	}
	// 小的插入左子节点
	if v < t.Value {
		t.Left = insert(t.Left, v)
		return t
	}
	// 大的插入右子结点
	t.Right = insert(t.Right, v)
	return t
}

func main() {
	t1 := New(9, 2)
	fmt.Println(*t1)
	fmt.Println((*t1.Left).Value)
	fmt.Println(Compare(t1, New(9, 2)))  // true(形状和值都一样)
	fmt.Println(Compare(t1, New(5, 2)))  // false(形状不一样)
	fmt.Println(Compare(t1, New(9, 3)))  // false(值不一样)
	fmt.Println(Compare(t1, New(11, 7))) // false(形状与值都不一样)
}
{0xc0000a8030 12 0xc0000a8060}
10
true
false
false
false
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

寅恪光潜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值