二叉树(二)--遍历

二叉树的遍历方式

从节点之间位置关系的角度:

  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