定义:二叉树是指树中节点的度不大于2(只能0、1、2)的有序树
如下图就是一个二叉树:
下面是关于二叉树遍历的代码实现。
定义二叉树
type TreeNode struct {
Val int
Left *TreeNode
Right *TreeNode
}
遍历二叉树
遍历二叉树有四种方式:
- 先序遍历:先访问跟根节点,再访问左子树,最后访问右子树
- 中序遍历:先访问跟左子树,再访问根节点,最后访问右子树
- 后序遍历:先访问跟左子树,再访问右子树,最后访问根节点
- 层次遍历:每一层从左到右访问每一个节点
先序,中序,后序比较简单,用递归即可实现
// 前序遍历
func preOrder(root *TreeNode) (res []int) {
if root == nil {
return
}
res = append(res, root.Val)
res = append(res, preOrder(root.Left)...)
res = append(res, preOrder(root.Right)...)
return res
}
// 中序遍历
func MidOrder(root *TreeNode) (res []int) {
if root == nil {
return
}
res = append(res, MidOrder(root.Left)...)
res = append(res, root.Val)
res = append(res, MidOrder(root.Right)...)
return res
}
// 后序遍历
func PostOrder(root *TreeNode) (res []int) {
if root == nil {
return
}
res = append(res, PostOrder(root.Left)...)
res = append(res, PostOrder(root.Right)...)
res = append(res, root.Val)
return res
}
层次遍历稍微复杂一些,用到了广度优先遍历,用队列来实现
- 先将根节点放入队列
- 记录当前节点的Val,出队列,如果左子树有孩子,入队,如果右子树有孩子,入队
- 重复操作2,直到队列为空
// 层次遍历
func levelOrder(root *TreeNode) [][]int {
// 定义返回二维数组
ret := [][]int{}
if root == nil {
return ret
}
// 记录每一层的节点
temp := []int{}
// 根节点入队
queue := []*TreeNode{root}
// 队列不为空
for len(queue) > 0 {
// 后续有入队操作,保存当前len(queue)
length := len(queue)
// 更新
temp = []int{}
for i := 0; i < length; i++ {
// 记录当前节点
node := queue[0]
// 出队
queue = queue[1:]
// 如果有左孩子,入队
if node.Left != nil {
queue = append(queue, node.Left)
}
// 如果有右孩子,入队
if node.Right != nil {
queue = append(queue, node.Right)
}
// 记录当前节点Val
temp = append(temp, node.Val)
}
ret = append(ret, temp)
}
return ret
}
按上图设计二叉树,验证上述各遍历算法的准确性
func main() {
root := &TreeNode{
Val: 1,
Left: &TreeNode{
Val: 2,
Left: &TreeNode{
Val: 4,
Left: nil,
Right: nil,
},
Right: &TreeNode{
Val: 5,
Left: nil,
Right: nil,
},
},
Right: &TreeNode{
Val: 3,
Left: &TreeNode{
Val: 6,
Left: nil,
Right: nil,
},
Right: nil,
},
}
res := preOrder(root)
fmt.Println("前序遍历", res) // 前序遍历 [1 2 4 5 3 6]
res = MidOrder(root)
fmt.Println("中序遍历", res) // 中序遍历 [4 2 5 1 6 3]
res = PostOrder(root)
fmt.Println("后序遍历", res) // 后序遍历 [4 5 2 6 3 1]
levelOr := levelOrder(root)
fmt.Println("层次遍历", levelOr) // 层次遍历 [[1] [2 3] [4 5 6]]
}