이진 트리 (2)-순회

이진 트리를 횡단하는 방법

노드 간의 위치 관계 관점에서 :

  1. 선주문 순회
  2. 순회 순회
  3. 주문 후 순회
  4. 시퀀스 순회

보다 거시적 인 관점에서 :

  1. 깊이 우선 순회 (선주문 순회, 중간 순회, 후속 순회)
  2. 너비 첫 번째 순회 (계층 순서 순회)

깊이 첫 번째 순회

선주문 순회

바이너리 트리의 사전 순회, 출력 순서는 루트 노드, 왼쪽 하위 트리, 오른쪽 하위 트리 (루트 왼쪽 및 오른쪽이라고도 함)입니다.

순회 순회

바이너리 트리의 중간 순서 순회에서 출력 순서는 왼쪽 하위 트리, 루트 노드, 오른쪽 하위 트리 (왼쪽 루트 오른쪽이라고도 함)입니다.

주문 후 순회

이진 트리의 사후 순회, 출력 순서는 왼쪽 하위 트리, 오른쪽 하위 트리, 루트 노드 (왼쪽 및 오른쪽 루트라고도 함)입니다.

재귀 적 구현

(순회 메소드의 객체가 노드라는 점은 주목할 가치가 있습니다)

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())
}


추천

출처blog.csdn.net/csdniter/article/details/109959674