이진 트리를 횡단하는 방법
노드 간의 위치 관계 관점에서 :
- 선주문 순회
- 순회 순회
- 주문 후 순회
- 시퀀스 순회
보다 거시적 인 관점에서 :
- 깊이 우선 순회 (선주문 순회, 중간 순회, 후속 순회)
- 너비 첫 번째 순회 (계층 순서 순회)
깊이 첫 번째 순회
선주문 순회
바이너리 트리의 사전 순회, 출력 순서는 루트 노드, 왼쪽 하위 트리, 오른쪽 하위 트리 (루트 왼쪽 및 오른쪽이라고도 함)입니다.
순회 순회
바이너리 트리의 중간 순서 순회에서 출력 순서는 왼쪽 하위 트리, 루트 노드, 오른쪽 하위 트리 (왼쪽 루트 오른쪽이라고도 함)입니다.
주문 후 순회
이진 트리의 사후 순회, 출력 순서는 왼쪽 하위 트리, 오른쪽 하위 트리, 루트 노드 (왼쪽 및 오른쪽 루트라고도 함)입니다.
재귀 적 구현
(순회 메소드의 객체가 노드라는 점은 주목할 가치가 있습니다)
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
TreeNode1 := NewTreeNode(6)
BinaryTree.HeadNode.Right = &TreeNode1
TreeNode2 := NewTreeNode(8)
BinaryTree.HeadNode.Left = &TreeNode2
//打印二叉树层序遍历结果
fmt.Println(BinaryTree.HeadNode.levelOrderTraversal())
}