在 Go 中,树(Tree)是一种非常重要的数据结构,它由若干个节点和它们之间的边组成。树的一个特点是每个节点只有一个父节点,而且没有环路。
树可以用来表示很多实际问题中的关系模型,例如文件系统、XML文档等。在算法领域中,树也被广泛应用于搜索、排序等问题中。
在 Go 中,我们可以使用结构体和指针来表示一棵树:
type TreeNode struct {
Val int
Left *TreeNode
Right *TreeNode
}
上述代码定义了一个简单的二叉树节点结构体。其中Val表示该节点存储的值,Left和Right分别指向左子树和右子树。
通过递归遍历二叉树可以实现以下操作:
- 前序遍历(Preorder Traversal)
前序遍历就是先访问当前节点再依次访问左子树和右子树。具体实现如下:
func preOrder(root *TreeNode) {
if root == nil {
return
}
fmt.Println(root.Val) // 先访问当前节点
preOrder(root.Left) // 再依次访问左子树和右子树
preOrder(root.Right)
}
- 中序遍历(Inorder Traversal)
中序遍历是先访问左子树,再访问当前节点,最后访问右子树。具体实现如下:
func inOrder(root *TreeNode) {
if root == nil {
return
}
inOrder(root.Left) // 先访问左子树
fmt.Println(root.Val) // 再访问当前节点
inOrder(root.Right) // 最后访问右子树
}
- 后序遍历(Postorder Traversal)
后序遍历是先访问左子树,再访问右子树,最后访问当前节点。具体实现如下:
func postOrder(root *TreeNode) {
if root == nil {
return
}
postOrder(root.Left) // 先访问左子树和右子树
postOrder(root.Right)
fmt.Println(root.Val) // 最后访问当前节点
}
- 层序遍历(Level Order Traversal)
层序遍历就是按照从上到下、从左到右的顺序逐层遍历整棵二叉树。具体实现可以使用队列来辅助实现:
func levelOrder(root *TreeNode) [][]int {
var res [][]int
if root == nil {
return res
}
queue := []*TreeNode{root} // 初始化一个队列,并将根节点放入其中
for len(queue) > 0 { // 队列不为空时循环
size := len(queue) // 记录当前层的节点数
var curLevel []int
for i := 0; i < size; i++ {
curNode := queue[0] // 取出队列中第一个节点
queue = queue[1:] // 将队列中第一个节点弹出
curLevel = append(curLevel, curNode.Val) // 将当前节点值放入到该层的结果数组中
if curNode.Left != nil { // 如果有左子树,则将其加入到队列中
queue = append(queue, curNode.Left)
}
if curNode.Right != nil { // 如果有右子树,则将其加入到队列中
queue = append(queue, curNode.Right)
}
}
res = append(res, curLevel) // 将该层结果添加到最终结果数组中
}
return res
}
除了以上常见操作之外,还可以对树进行搜索、插入、删除等操作。总之,掌握了树的基本操作和实现方式,就能够更好地理解和使用 Go 中许多与树相关的算法和数据结构。




