Binary tree (two)-traversal

The way to traverse the binary tree

From the perspective of the positional relationship between nodes:

  1. Preorder traversal
  2. In-order traversal
  3. Post-order traversal
  4. Sequence traversal

From a more macro perspective:

  1. Depth-first traversal (pre-order traversal, middle-order traversal, subsequent traversal)
  2. 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())
}


Guess you like

Origin blog.csdn.net/csdniter/article/details/109959674