【Golang】Go语言编程思想(六):Channel,第三节,使用Channel实现树的遍历

使用 Channel 实现树的遍历

tree

在此处简单回顾一下之前学过的二叉树遍历,首先新建一个名为 tree 的目录,并在其下对文件和子目录进行如下组织:

其中 node.go 存放的是 Node 的定义:

go 复制代码
package tree

import "fmt"

type Node struct {
	Value       int
	Left, Right *Node
}

func (node Node) Print() {
	fmt.Print(node.Value, " ")
}

func (node *Node) SetValue(value int) {
	if node == nil {
		fmt.Println("Setting Value to nil" +
			" node. Ignored.")
		return
	}
	node.Value = value
}

func CreateNode(value int) *Node { return &Node{Value: value} }

// 👆 构建 Node 的工厂函数, Golang 支持返回局部变量的地址

traverse.go 存放的是树的遍历方法,使用的方法是中序遍历,下例还将展示如何以函数作为中序遍历的参数在 Golang 当中实现在树的遍历过程中的某些结点行为(本例实现行为是,当遍历到某个结点时,将其打印出来):

go 复制代码
package tree

import "fmt"

func (node *Node) Traverse() {
	node.TraverseFunc(func(n *Node) {
		n.Print()
	})
	fmt.Println()
}

func (node *Node) TraverseFunc(f func(*Node)) {
	if node == nil {
		return
	}
	node.Left.TraverseFunc(f)
	f(node)
	node.Right.TraverseFunc(f)
}

最后,entry.go 建立了一棵树:

go 复制代码
package main

import (
	"fmt"
	"learngo/tree"
)

func main() {
	var root tree.Node
	root = tree.Node{Value: 3}
	root.Left = &tree.Node{}
	root.Right = &tree.Node{5, nil, nil}
	root.Right.Left = new(tree.Node)
	root.Left.Right = tree.CreateNode(2)
	root.Right.Left.SetValue(4)

	fmt.Print("In-order traversal: ")
	root.Traverse()
}

使用 Channel 统计最大的结点下标

此处我们实现一个最简单的 Channel 遍历树的应用,即统计最大的结点下标,在 traverse.go 当中编写如下函数:

go 复制代码
// 👇 使用 Channel 来完成树的遍历
func (node *Node) TraverseWithChannel() chan *Node {
	// 调用 TraverseWithChannel 获得的返回值是 chan *Node
	out := make(chan *Node)
	go func() {
		node.TraverseFunc(func(node *Node) {
			out <- node
		})
		close(out)
	}()
	return out
}

函数的返回值是 chan *Node ,即一个类行为 *Node 的通道。函数体当中的行为如下:

首先使用 make 方法新建一个通道,之后开启协程,将结点的值写入到通道当中。完成写入之后使用 close 方法关闭通道。

协程启动之后将通道返回。

在 main 函数中添加以下片段进行验证:

go 复制代码
c := root.TraverseWithChannel()
maxNode := 0 // 统计最大的结点数
for node := range c {			// 不断地接受来自 channel 的信息
	if node.Value > maxNode {
		maxNode = node.Value
	}
}
fmt.Println("Max Node Value:", maxNode)
相关推荐
小小龙学IT2 小时前
Go 语言后端开发:从并发模型到生产落地的工程实践
开发语言·后端·golang
oqX0Cazj22 小时前
2026超火Go-Zero实战:从架构原理到高并发接口落地,彻底解决接口超时、雪崩问题
开发语言·架构·golang
go不是csgo8 小时前
从0到1理解Go熔断器:sony/gobreaker 源码剖析 + 仿TikTok Feed 项目实战
开发语言·后端·golang
oqX0Cazj29 小时前
Go-Zero数据库事务实战:本地事务+失败自动回滚+生产避坑+简单分布式事务方案
数据库·分布式·golang
右耳朵猫AI9 小时前
Go周刊2026W22 | GoReleaser 2.16、chi 5.3、tldx 1.4、wazero 1.12、Buf 1.70
开发语言·后端·golang
踏着七彩祥云的小丑9 小时前
Go学习第3天:变量+常量+运算符
开发语言·学习·golang·go
晨曦中的暮雨21 小时前
Golang速通(Javaer版)
java·开发语言·后端·golang
codeejun1 天前
每日一Go-76(架构篇)|多集群部署 / 容灾 / Failover / Backup / 热迁移
开发语言·架构·golang
迷茫运维路1 天前
golang_Viper配置管理器
后端·golang
geovindu1 天前
go: Broadcast Pattern
开发语言·后端·设计模式·golang·广播模式