Skip to content

Instantly share code, notes, and snippets.

@x893675
Created September 13, 2020 07:41
Show Gist options
  • Save x893675/1aabb16184820cbe263a67286b7d38f0 to your computer and use it in GitHub Desktop.
Save x893675/1aabb16184820cbe263a67286b7d38f0 to your computer and use it in GitHub Desktop.
package main
import "fmt"
type TreeNode struct {
Val int
Left *TreeNode
Right *TreeNode
}
// 递归前序遍历
func preorderTraversal(root *TreeNode) {
if root == nil {
return
}
// 先访问根再访问左右
fmt.Println(root.Val)
preorderTraversal(root.Left)
preorderTraversal(root.Right)
}
func preorderTraversal2(root *TreeNode) []int {
if root == nil {
return nil
}
result := make([]int, 0)
stack := make([]*TreeNode, 0)
for root != nil || len(stack) != 0 {
for root != nil {
result = append(result, root.Val)
stack = append(stack, root)
root = root.Left
}
root = stack[len(stack)-1].Right
stack = stack[:len(stack)-1]
}
return result
}
func inorderTraversal(root *TreeNode) []int {
if root == nil {
return nil
}
result := make([]int, 0)
stack := make([]*TreeNode, 0)
for root != nil || len(stack) != 0 {
for root != nil {
stack = append(stack, root)
root = root.Left
}
result = append(result, stack[len(stack)-1].Val)
root = stack[len(stack)-1].Right
stack = stack[:len(stack)-1]
}
return result
}
// 后序非递归
// 根节点必须在右节点弹出之后,再弹出
func postorderTraversal(root *TreeNode) []int {
if root == nil {
return nil
}
result := make([]int, 0)
stack := make([]*TreeNode, 0)
var lastVisit *TreeNode
for root != nil || len(stack) != 0 {
for root != nil {
stack = append(stack, root)
root = root.Left
}
node := stack[len(stack)-1]
if node.Right == nil || node.Right == lastVisit {
stack = stack[:len(stack)-1]
result = append(result, node.Val)
lastVisit = node
} else {
root = node.Right
}
}
return result
}
/*
3
/ \
9 20
/ / \
8 15 7
/ \
5 10
/
4
*/
//preorder = [3, 9, 8, 5, 4, 10, 20, 15, 7]
//inorder = [4, 5, 8, 10, 9, 3, 15, 20, 7]
//postorder = [4, 5, 10, 8, 9, 15, 7, 20, 3]
func buildBinaryTree(preorder []int, inorder []int) *TreeNode {
if len(preorder) == 0 {
return nil
}
root := &TreeNode{preorder[0], nil, nil}
stack := []*TreeNode{}
stack = append(stack, root)
var inorderIndex int
for i := 1; i < len(preorder); i++ {
preorderVal := preorder[i]
node := stack[len(stack)-1]
if node.Val != inorder[inorderIndex] {
node.Left = &TreeNode{preorderVal, nil, nil}
stack = append(stack, node.Left)
} else {
for len(stack) != 0 && stack[len(stack)-1].Val == inorder[inorderIndex] {
node = stack[len(stack)-1]
stack = stack[:len(stack)-1]
inorderIndex++
}
node.Right = &TreeNode{preorderVal, nil, nil}
stack = append(stack, node.Right)
}
}
return root
}
//dfs 深度优先,从上到下
func DFSTraversal(root *TreeNode) []int {
result := make([]int, 0)
dfs(root, &result)
return result
}
func dfs(root *TreeNode, result *[]int) {
if root == nil {
return
}
*result = append(*result, root.Val)
dfs(root.Left, result)
dfs(root.Right, result)
}
// DFS 深度搜索-从下向上(分治法)
func DFSTraversal2(root *TreeNode) []int {
return divideAndConquer(root)
}
func divideAndConquer(root *TreeNode) []int {
result := make([]int, 0)
if root == nil {
return result
}
left := divideAndConquer(root.Left)
right := divideAndConquer(root.Right)
result = append(result, root.Val)
result = append(result, left...)
result = append(result, right...)
return result
}
// BFS 层次遍历
func levelOrder(root *TreeNode) [][]int {
if root == nil {
return nil
}
result := make([][]int, 0)
queue := make([]*TreeNode, 0)
queue = append(queue, root)
for len(queue) != 0 {
l := len(queue)
list := make([]int, 0)
for i := 0; i < l; i++ {
level := queue[0]
queue = queue[1:]
list = append(list, level.Val)
if level.Left != nil {
queue = append(queue, level.Left)
}
if level.Right != nil {
queue = append(queue, level.Right)
}
}
result = append(result, list)
}
return result
}
func main() {
preorder := []int{3, 9, 8, 5, 4, 10, 20, 15, 7}
inorder := []int{4, 5, 8, 10, 9, 3, 15, 20, 7}
t := buildBinaryTree(preorder, inorder)
result := levelOrder(t)
fmt.Println(result)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment