📌算法Go语言描述📌algorithm📌binary_tree.go
package algorithm
import "fmt"
type TreeNode struct {
Val int
Left *TreeNode
Right *TreeNode
}
/*
4
/\
2 6
/| |\
1 3 5 8
/ |\
0 7 9
*/
var tree = &TreeNode{
Val: 4,
Left: &TreeNode{
Val: 2,
Left: &TreeNode{
Val: 1,
Left: &TreeNode{
Val: 0,
},
},
Right: &TreeNode{
Val: 3,
},
},
Right: &TreeNode{
Val: 6,
Left: &TreeNode{
Val: 5,
},
Right: &TreeNode{
Val: 8,
Left: &TreeNode{
Val: 7,
},
Right: &TreeNode{
Val: 9,
},
},
},
}
//深度优先遍历(Depth-First-Search):先序、中序、后序
//广度优先遍历(Breadth-First-Search):层序
// 先序遍历递归
func PreOrderTraversal(node *TreeNode) {
if node != nil {
fmt.Print(node.Val, " ")
PreOrderTraversal(node.Left)
PreOrderTraversal(node.Right)
}
} // 4 2 1 0 3 6 5 8 7 9
// 中序遍历递归
func InOrderTraversal(node *TreeNode) {
if node != nil {
InOrderTraversal(node.Left)
fmt.Print(node.Val, " ")
InOrderTraversal(node.Right)
}
} //0 1 2 3 4 5 6 7 8 9
// 后续遍历递归
func PostOrderTraversal(node *TreeNode) {
if node != nil {
PostOrderTraversal(node.Left)
PostOrderTraversal(node.Right)
fmt.Print(node.Val, " ")
}
} // 0 1 3 2 5 7 9 8 6 4
// 先序遍历模拟栈代替递归
func (node *TreeNode) PreOrderTraversal() {
if node == nil {
return
}
var stack []*TreeNode
p := node
for p != nil || len(stack) > 0 {
for p != nil { //到最左下叶
fmt.Print(p.Val, " ") //访问结点
stack = append(stack, p) //结点入栈
p = p.Left
}
p = stack[len(stack)-1] //结点不再访问
stack = stack[:len(stack)-1] //直接弹出
p = p.Right
}
} // 4 2 1 0 3 6 5 8 7 9
// 中序遍历模拟栈代替递归
func (node *TreeNode) InOrderTraversal() {
if node == nil {
return
}
var stack []*TreeNode
p := node
for p != nil || len(stack) > 0 {
for p != nil { //到最左下叶
stack = append(stack, p) //结点入栈
p = p.Left
}
p = stack[len(stack)-1]
stack = stack[:len(stack)-1]
fmt.Print(p.Val, " ") //弹出时访问
p = p.Right
}
} // 0 1 2 3 4 5 6 7 8 9
// 后序遍历模拟栈代替递归
func (node *TreeNode) PostOrderTraversal() {
if node == nil {
return
}
var stack []*TreeNode
p := node
var tmp *TreeNode //辅助结点
for p != nil || len(stack) > 0 {
for p != nil {
stack = append(stack, p)
p = p.Left
}
p = stack[len(stack)-1] //获取栈顶元素,先不出栈
if p.Right != nil && p.Right != tmp { //右子树不为空且未访问
p = p.Right
} else { //右子树已经访问或为空,接下来出栈访问结点,第二次栈顶
fmt.Print(p.Val, " ")
stack = stack[:len(stack)-1] //出栈
tmp = p //指向访问过的右子树结点
p = nil //使得p为空继续访问栈顶
}
}
} // 0 1 3 2 5 7 9 8 6 4
// 层序遍历:每一层从左到右访问每一个节点,需要使用辅助的先进先出的队列。
func (node *TreeNode) LevelOrderTraversal() {
if node == nil {
return
}
queue := []*TreeNode{node}
for len(queue) > 0 {
p := queue[0]
queue = queue[1:] //队头元素不断出队
fmt.Print(p.Val, " ")
if p.Left != nil {
queue = append(queue, p.Left) //左子树非空,入队列
}
if p.Right != nil {
queue = append(queue, p.Right) //右子树非空,入队列
}
}
} // 4 2 6 1 3 5 8 0 7 9
// 层序遍历分层打印
func (node *TreeNode) LevelTraversal() {
if node == nil {
return
}
level := 1
queue := []*TreeNode{node}
for size := 1; size > 0; size = len(queue) {
fmt.Printf("\n<%v>:", level)
for i := 0; i < size; i++ { //遍历本层
p := queue[i]
fmt.Print(" ", p.Val)
if p.Left != nil {
queue = append(queue, p.Left)
}
if p.Right != nil {
queue = append(queue, p.Right)
}
}
queue = queue[size:] //整层出队
level++
}
} /*
<1>: 4
<2>: 2 6
<3>: 1 3 5 8
<4>: 0 7 9
*/
// 根据先序和中序遍历构建二叉树
func BuildTree(preorder []int, inorder []int) *TreeNode {
size := len(preorder)
if size == 0 {
return nil
}
root := &TreeNode{Val: preorder[0]} //先序遍历最先访问根结点
i := 0
for i < size {
if inorder[i] == root.Val {
break
}
i++
}
root.Left = BuildTree(preorder[1:i+1], inorder[:i])
root.Right = BuildTree(preorder[i+1:], inorder[i+1:])
return root
}
func BuildTreeByPreorder(preorder []int, inorder []int) *TreeNode {
size := len(preorder)
if size == 0 {
return nil
}
root := &TreeNode{Val: preorder[0]}
stack := []*TreeNode{root}
inorderIndex := 0
for i := 1; i < len(preorder); i++ {
p := stack[len(stack)-1]
node := &TreeNode{Val: preorder[i]}
if p.Val != inorder[inorderIndex] {
p.Left = node
} else {
for len(stack) > 0 && stack[len(stack)-1].Val == inorder[inorderIndex] {
p = stack[len(stack)-1]
stack = stack[:len(stack)-1]
inorderIndex++
}
p.Right = node
}
stack = append(stack, node)
}
return root
}
// 根据中序和后序遍历构建二叉树
func CreateTree(inorder []int, postorder []int) *TreeNode {
size := len(inorder)
if size == 0 {
return nil
}
root := &TreeNode{Val: postorder[size-1]} //后序遍历最后访问根结点
i := 0
for i < size {
if inorder[i] == root.Val {
break
}
i++
}
root.Left = CreateTree(inorder[:i], postorder[:i])
root.Right = CreateTree(inorder[i+1:], postorder[i:size-1])
return root
}
func CreateTreeByPostorder(inorder []int, postorder []int) *TreeNode {
size := len(inorder)
if size == 0 {
return nil
}
root := &TreeNode{Val: postorder[size-1]}
stack := []*TreeNode{root}
inorderIndex := size - 1
for i := size - 2; i >= 0; i-- {
p := stack[len(stack)-1]
node := &TreeNode{Val: postorder[i]}
if p.Val != inorder[inorderIndex] {
p.Right = node
} else {
for len(stack) > 0 && stack[len(stack)-1].Val == inorder[inorderIndex] {
p = stack[len(stack)-1]
stack = stack[:len(stack)-1]
inorderIndex--
}
p.Left = node
}
stack = append(stack, node)
}
return root
}