二叉树(二)--遍历

二叉树的遍历方式

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

  1. 前序遍历
  2. 中序遍历
  3. 后序遍历
  4. 层序遍历

从更宏观的角度:

  1. DFS(深度优先遍历)(前序遍历,中序遍历,后续遍历)
  2. 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())
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值