二叉树遍历有常见的前序、中序、后续遍历,也有深度优先(DFS),广度优先(BFS)等多种的遍历方式,了解好基本的底层遍历规则对解决很多上层问题都有许多帮助,例如常见的层次问题,最短距离基本都是采用广度优先搜索(BFS)。
type TreeNode struct {
Val int
Left *TreeNode
Right *TreeNode
}
前序遍历
中-左-右
func preOrder(node *TreeNode) {
if node == nil {
return
}
log.Println(node.Val)
preOrder(node.Left)
preOrder(node.Right)
}
中序遍历
左-中-右
func midOrder(node *TreeNode) {
if node == nil {
return
}
midOrder(node.Left)
log.Println(node.Val)
midOrder(node.Right)
}
后续遍历
左-右-中
func subOrder(node *TreeNode) {
if node == nil {
return
}
subOrder(node.Left)
subOrder(node.Right)
log.Println(node.Val)
}
BFS
使用链表实现
func bfsListOrder(node *TreeNode) {
if node == nil {
return
}
var queue list.List
queue.PushBack(node)
for queue.Len() > 0 {
element := queue.Front()
queue.Remove(element)
if element == nil {
continue
}
curNode, ok := element.Value.(*TreeNode)
if !ok {
continue
}
if curNode != nil {
log.Println(curNode.Val)
}
if curNode.Left != nil {
queue.PushBack(curNode.Left)
}
if curNode.Right != nil {
queue.PushBack(curNode.Right)
}
}
}
使用数组实现
func bfsOrder(node *TreeNode) {
if node == nil {
return
}
var queue []*TreeNode
queue = append(queue, node)
for len(queue) > 0 {
curNode := queue[0]
if curNode != nil {
log.Println(curNode.Val)
}
if curNode.Left != nil {
queue = append(queue, curNode.Left)
}
if curNode.Right != nil {
queue = append(queue, curNode.Right)
}
queue = queue[1:]
}
}
DFS
// 深度优先遍历
// 核心数据结构是”栈“
func DFSOrder(root *TreeNode) {
if root == nil {
return
}
stack := list.List{}
stack.PushBack(root)
for stack.Len() > 0 {
element := stack.Back()
if element == nil {
continue
}
stack.Remove(element)
node, ok := element.Value.(*TreeNode)
if !ok {
continue
}
fmt.Println(node.Val)
if node.Right != nil {
stack.PushBack(node.Right)
}
if node.Left != nil {
stack.PushBack(node.Left)
}
}
}
参考
LeetCode 例题精讲 | 13 BFS 的使用场景:层序遍历、最短路径问题 (qq.com)
深度优先搜索的理解与简单实现 (juejin.cn)