二叉树的遍历方式
从节点之间位置关系的角度:
- 前序遍历
- 中序遍历
- 后序遍历
- 层序遍历
从更宏观的角度:
- DFS(深度优先遍历)(前序遍历,中序遍历,后续遍历)
- BFS(广度优先遍历)(层序遍历)
深度优先遍历
前序遍历
二叉树的前序遍历,输出顺序是根节点,左子树,右子树(也叫做根左右)
中序遍历
二叉树的中序遍历,输出顺序是左子树,根节点,右子树(也叫做左根右)
后序遍历
二叉树的后序遍历,输出顺序是左子树,右子树,根节点(也叫做左右根)
递归实现
(值得注意的是遍历方法的对象是节点)
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))
}
非递归实现
以前序遍历为例,其余同
绝大多数可以用递归解决的问题,都可以用另一种数据结构 栈
来解决。因为递归和栈都有回溯的特性
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())
}
广度优先遍历
也即层序遍历,按照二叉树根节点和叶子节点的层次关系,一层一层地横向遍历各个节点
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
TreeNode2 := NewTreeNode(8)
BinaryTree.HeadNode.Left = &TreeNode2
TreeNode1 := NewTreeNode(6)
BinaryTree.HeadNode.Right = &TreeNode1
//打印二叉树层序遍历结果
fmt.Println(BinaryTree.HeadNode.levelOrderTraversal())
}