The way to traverse the binary tree
From the perspective of the positional relationship between nodes:
- Preorder traversal
- In-order traversal
- Post-order traversal
- Sequence traversal
From a more macro perspective:
- Depth-first traversal (pre-order traversal, middle-order traversal, subsequent traversal)
- Breadth first traversal (layer order traversal)
Depth first traversal
Preorder traversal
Preorder traversal of binary tree, output order is root node, left subtree, right subtree (also called root left and right)
In-order traversal
In the middle order traversal of the binary tree, the output order is left subtree, root node, right subtree (also called left root right)
Post-order traversal
Post-order traversal of binary tree, the output order is left subtree, right subtree, root node (also called left and right root)
Recursive implementation
(It is worth noting that the object of the traversal method is a node)
package main
import "fmt"
// 二叉树
type BinaryTree struct {
HeadNode *TreeNode
}
//二叉树节点
type TreeNode struct {
Data int32 // 链表上的数据
Left *TreeNode // 指针指向左孩子节点
Right *TreeNode // 指针指向右孩子节点
}
func NewBinaryTree() BinaryTree {
BinaryTree := BinaryTree{
HeadNode: nil}
return BinaryTree
}
// 以二叉查找树的定义添加元素,手动一个一个地添加也可以
func (self *BinaryTree) Add(value int32) bool {
neWNode := &TreeNode{
Data: value,}
node := self.HeadNode
if node == nil {
self.HeadNode = neWNode
return true
}
for node.Data != value {
if value < node.Data {
if node.Left != nil {
node = node.Left
} else {
node.Left = neWNode
return true
}
}
if value > node.Data {
if node.Right != nil {
node = node.Right
} else {
node.Right = neWNode
return true
}
}
}
return false
}
//前序遍历
func (self *TreeNode) preOrderTraversal(res *[]int32)[]int32 {
if self == nil {
return *res
}
*res = append(*res, self.Data)
self.Left.preOrderTraversal(res)
self.Right.preOrderTraversal(res)
return *res
}
//中序遍历
func (self *TreeNode) inOrderTraversal(res *[]int32)[]int32 {
if self == nil {
return *res
}
self.Left.inOrderTraversal(res)
*res = append(*res, self.Data)
self.Right.inOrderTraversal(res)
return *res
}
//后序遍历
func (self *TreeNode) postOrderTraversal(res *[]int32)[]int32 {
if self == nil {
return *res
}
self.Left.postOrderTraversal(res)
self.Right.postOrderTraversal(res)
*res = append(*res, self.Data)
return *res
}
func main() {
BinaryTree := NewBinaryTree()
BinaryTree.Add(4)
BinaryTree.Add(5)
BinaryTree.Add(3)
var res []int32
fmt.Println(BinaryTree.HeadNode.preOrderTraversal(&res))
//fmt.Println(BinaryTree.HeadNode.inOrderTraversal(&res))
//fmt.Println(BinaryTree.HeadNode.postOrderTraversal(&res))
}
Non-recursive implementation
Take the previous order traversal as an example, the rest are the same
The vast majority can use recursion to solve the problem, you can use another data structure 栈
to solve. Because both recursion and stack have backtracking characteristics
package main
import (
"errors"
"fmt"
)
type Stack struct {
arr []interface{
} //切片
stackSize int //栈中元素的个数
}
func NewStack() Stack {
stack := Stack{
arr: make([]interface{
}, 0)}
return stack
}
//push栈元素
func (s *Stack) push(t interface{
}) {
s.arr = append(s.arr, t)
s.stackSize += 1
}
//pop栈元素
func (s *Stack) pop() interface{
} {
if s.stackSize > 0 {
//栈不为空时
s.stackSize--
element := s.arr[s.stackSize]
s.arr = s.arr[:s.stackSize]
return element
}
return errors.New("栈为空")
}
// 二叉树
type BinaryTree struct {
HeadNode *TreeNode
}
//二叉树节点
type TreeNode struct {
Data int32 // 链表上的数据
Left *TreeNode // 指针指向左孩子节点
Right *TreeNode // 指针指向右孩子节点
}
func NewBinaryTree() BinaryTree {
BinaryTree := BinaryTree{
HeadNode: nil}
return BinaryTree
}
func NewTreeNode(value int32) TreeNode {
TreeNode := TreeNode{
Data: value}
return TreeNode
}
//非递归前序遍历
func (node *TreeNode)preOrderTraversalWithStack() []int32 {
var res []int32
stack := NewStack()
for node != nil || stack.stackSize > 0 {
for node != nil {
res = append(res, node.Data)
stack.push(node)
node=node.Left
}
if stack.stackSize>0{
node=stack.pop().(*TreeNode)
node=node.Right
}
}
return res
}
func main() {
BinaryTree := NewBinaryTree()
//手动创建二叉树
TreeNode := NewTreeNode(2)
BinaryTree.HeadNode = &TreeNode
TreeNode1 := NewTreeNode(3)
BinaryTree.HeadNode.Right = &TreeNode1
TreeNode2 := NewTreeNode(4)
BinaryTree.HeadNode.Left = &TreeNode2
//打印非递归前序遍历结果
fmt.Println(BinaryTree.HeadNode.preOrderTraversalWithStack())
}
Breadth first traversal
That is, layer sequence traversal, according to the hierarchical relationship between the root node and the leaf node of the binary tree, each node is traversed horizontally one by one
package main
import (
"errors"
"fmt"
)
// 队列,以切片的最后一个元素为对头,第一个元素为队尾
type Queen struct {
arr []interface{
} //切片
stackSize int //栈中元素的个数
}
func NewQueen() Queen {
stack := Queen{
arr: make([]interface{
}, 0)}
return stack
}
//push队列元素
func (s *Queen) push(t interface{
}) {
s.arr = append(s.arr, t)
s.stackSize += 1
}
//pop队列元素
func (s *Queen) pop() interface{
} {
if s.stackSize > 0 {
//栈不为空时
element := s.arr[0]
s.arr = s.arr[1:s.stackSize]
s.stackSize--
return element
}
return errors.New("队列为空")
}
// 二叉树
type BinaryTree struct {
HeadNode *TreeNode
}
//二叉树节点
type TreeNode struct {
Data int32 // 链表上的数据
Left *TreeNode // 指针指向左孩子节点
Right *TreeNode // 指针指向右孩子节点
}
func NewBinaryTree() BinaryTree {
BinaryTree := BinaryTree{
HeadNode: nil}
return BinaryTree
}
func NewTreeNode(value int32) TreeNode {
TreeNode := TreeNode{
Data: value}
return TreeNode
}
//层序遍历
func (node *TreeNode) levelOrderTraversal() []int32 {
queen := NewQueen()
var res []int32
if node == nil {
return res
}
queen.push(node)
for queen.stackSize != 0 {
node = queen.pop().(*TreeNode)
res = append(res, node.Data)
if node.Left != nil {
queen.push(node.Left)
}
if node.Right != nil {
queen.push(node.Right)
}
}
return res
}
func main() {
BinaryTree := NewBinaryTree()
//手动创建二叉树
TreeNode := NewTreeNode(2)
BinaryTree.HeadNode = &TreeNode
TreeNode1 := NewTreeNode(6)
BinaryTree.HeadNode.Right = &TreeNode1
TreeNode2 := NewTreeNode(8)
BinaryTree.HeadNode.Left = &TreeNode2
//打印二叉树层序遍历结果
fmt.Println(BinaryTree.HeadNode.levelOrderTraversal())
}