一.前序遍历

   前序遍历按照“根结点-左孩子-右孩子”的顺序进行访问。

二.中序遍历

  中序遍历按照“左孩子-根结点-右孩子”的顺序进行访问。

三.后序遍历

 后序遍历按照“左孩子-右孩子-根结点”的顺序进行访问。

总结:由根节点在前中后决定前中后序,三种遍历代码逻辑一样,只是打印位置不一样,非递归方式后续遍历需要两个栈后进先出打印

解决方式

1,递归

func inorderTraversal(root *TreeNode){
    if root!=nil{
         //前序在这里打印
        inorderTraversal(root.Left)
        //中序在这里打印
        r:=inorderTraversal(root.Right)
        //后序在这里打印
    }
}

2,非递归

func inorderTraversal(root *TreeNode){
    var s Stack   
    cur:=root
    for !s.empty() || cur!=nil{
        for cur!=nil{
             //前序遍历,在这里打印value
             s.push(cur)
             cur=cur.Left
        }
        if !s.empty(){//注意这里是判断不是循环
            cur=s.pop()
             //中序遍历,在这里打印value
            cur=cur.Right
            //后续遍历在这里打印但是,需要加个标识,是否进过栈,进过才打印
        }
    }
}

golang中序遍历实现例子

递归

/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */
func inorderTraversal(root *TreeNode) []int {
    var m []int
    if root!=nil{
        l:=inorderTraversal(root.Left)
        m=append(l,root.Val)
        r:=inorderTraversal(root.Right)
        m=append(m,r...)
    }
    return m
}

非递归

/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */
func inorderTraversal(root *TreeNode) []int {
    var m []int
    var s Stack   
    cur:=root
    for !s.empty() || cur!=nil{
        for cur!=nil{
             s.push(cur)
            cur=cur.Left
        }
        if !s.empty(){
            cur=s.pop()
            m=append(m,cur.Val)
            cur=cur.Right
        }
    }
    return m
}

type Stack struct{
    data []*TreeNode
}

func (s*Stack)empty() bool{
    return len(s.data)==0
}
func (s* Stack)push(node* TreeNode){
    s.data=append( s.data,node)
}

func (s*Stack)pop()(node* TreeNode){
    if len(s.data)==0{
        return nil
    }
    node=s.data[len(s.data)-1]
    s.data=s.data[0:len(s.data)-1]
    return node
}
func (s*Stack)printSelf(){
    for i:=0;i<len(s.data);i++{
        fmt.Print((*s.data[i]).Val)
    }
    fmt.Println("")
}

后序遍历+将list转化成二叉树

package main

import (
  "fmt"
  "strconv"
)

func main() {
  h := sliceToTree(parseSlice([]string{"1", "null", "2", "3", "null", "5", "4"}))
  walkTree(h)
  fmt.Println(inorderTraversal(h))
}

type TreeNode struct {
  Val   int
  Left  *TreeNode
  Right *TreeNode
}

func walkTree(h *TreeNode) {
  if h != nil {
    walkTree(h.Left)
    walkTree(h.Right)
    fmt.Println(h.Val)
  }
}
func parseSlice(vals []string) []*TreeNode {
  if len(vals) < 1 {
    return nil
  }
  st := make([]*TreeNode, len(vals))
  for i := 0; i < len(vals); i++ {
    if vals[i] == "null" {
      st[i] = nil
      continue
    }
    i32, e := strconv.ParseInt(vals[i], 10, 32)
    if e != nil {
      st[i] = nil
      continue
    }
    st[i] = &TreeNode{int(i32), nil, nil}
  }
  return st
}
func sliceToTree(st []*TreeNode) (h *TreeNode) {
  if len(st) < 1 {
    return nil
  }
  if len(st) == 1 || st[0] == nil {
    return st[0]
  }
  h, s := fillChild(st[0], st[1:len(st)])
  cur := h
  for len(s) > 0 {
    if cur.Left != nil && cur.Right != nil {
      cur.Left, s = fillChild(cur.Left, s)
      cur.Right, s = fillChild(cur.Right, s)
      cur = cur.Left
      continue
    }
    if cur.Left != nil {
      cur.Left, s = fillChild(cur.Left, s)
      cur = cur.Left
      continue
    }
    if cur.Right != nil {
      cur.Right, s = fillChild(cur.Right, s)
      cur = cur.Right
    }
  }
  return h

}

func fillChild(h *TreeNode, st []*TreeNode) (*TreeNode, []*TreeNode) {
  if len(st) < 1 {
    return h, nil
  }
  if len(st) == 1 {
    h.Left = st[0]
    return h, nil
  }
  if len(st) == 2 {
    h.Left = st[0]
    h.Right = st[1]
    return h, nil
  }
  h.Left = st[0]
  h.Right = st[1]
  return h, st[2:len(st)]
}

func inorderTraversal(root *TreeNode) []int {
  var m []int
  var s Stack
  var s2 Stack
  cur := root
  for !s.empty() || cur != nil {
    for cur != nil {
      s.push(cur)
      s2.push(cur)
      cur = cur.Right
    }
    if !s.empty() {
      cur = s.pop()
      cur = cur.Left
    }
  }
  for !s2.empty() {
    cur = s2.pop()
    if cur != nil {
      m = append(m, cur.Val)
    }
  }
  return m
}

type Stack struct {
  data []*TreeNode
}

func (s *Stack) empty() bool {
  return len(s.data) == 0
}
func (s *Stack) push(node *TreeNode) {
  s.data = append(s.data, node)
}

func (s *Stack) pop() (node *TreeNode) {
  if len(s.data) == 0 {
    return nil
  }
  node = s.data[len(s.data)-1]
  s.data = s.data[0 : len(s.data)-1]
  return node
}
func (s *Stack) printSelf() {
  for i := 0; i < len(s.data); i++ {
    fmt.Print((*s.data[i]).Val)
  }
  fmt.Println("")
}

层序遍历:

队列实现的基本思路:遍历从根节点开始,首先将根节点入队,然后执行循环:节点出队,访问(访问)根节点,将左儿子入队,将右儿子入队,直到队列为空停止

package main

import (
  "fmt"
  "strconv"
)

func main() {
  fmt.Println("Hello, 世界")
  h := sliceToTree(parseSlice([]string{"1", "null", "2", "3", "null", "5", "4"}))
  walkTree(h)
  fmt.Println(LevelOrderTraversal(h))
}

type TreeNode struct {
  Val   int
  Left  *TreeNode
  Right *TreeNode
}

func walkTree(h *TreeNode) {
  if h != nil {
    fmt.Println(h.Val)
    walkTree(h.Left)
    walkTree(h.Right)
  }
}
func parseSlice(vals []string) []*TreeNode {
  if len(vals) < 1 {
    return nil
  }
  st := make([]*TreeNode, len(vals))
  for i := 0; i < len(vals); i++ {
    if vals[i] == "null" {
      st[i] = nil
      continue
    }
    i32, e := strconv.ParseInt(vals[i], 10, 32)
    if e != nil {
      st[i] = nil
      continue
    }
    st[i] = &TreeNode{int(i32), nil, nil}
  }
  return st
}
func sliceToTree(st []*TreeNode) (h *TreeNode) {
  if len(st) < 1 {
    return nil
  }
  if len(st) == 1 || st[0] == nil {
    return st[0]
  }
  h, s := fillChild(st[0], st[1:len(st)])
  cur := h
  for len(s) > 0 {
    if cur.Left != nil && cur.Right != nil {
      cur.Left, s = fillChild(cur.Left, s)
      cur.Right, s = fillChild(cur.Right, s)
      cur = cur.Left
      continue
    }
    if cur.Left != nil {
      cur.Left, s = fillChild(cur.Left, s)
      cur = cur.Left
      continue
    }
    if cur.Right != nil {
      cur.Right, s = fillChild(cur.Right, s)
      cur = cur.Right
    }
  }
  return h

}

func fillChild(h *TreeNode, st []*TreeNode) (*TreeNode, []*TreeNode) {
  if len(st) < 1 {
    return h, nil
  }
  if len(st) == 1 {
    h.Left = st[0]
    return h, nil
  }
  if len(st) == 2 {
    h.Left = st[0]
    h.Right = st[1]
    return h, nil
  }
  h.Left = st[0]
  h.Right = st[1]
  return h, st[2:len(st)]
}

func LevelOrderTraversal(root *TreeNode) []int {
  var m []int
  if root == nil {
    return m
  }
  var q Queue
  q.push(root)
  for !q.empty() {
    cur := q.pop()
    m = append(m, cur.Val)
    if cur.Left != nil {
      q.push(cur.Left)
    }
    if cur.Right != nil {
      q.push(cur.Right)
    }
  }
  return m
}

type Queue struct {
  data []*TreeNode
}

func (s *Queue) empty() bool {
  return len(s.data) == 0
}
func (s *Queue) push(node *TreeNode) {
  s.data = append(s.data, node)
}

func (s *Queue) pop() (node *TreeNode) {
  if len(s.data) == 0 {
    return nil
  }
  node = s.data[0]
  if len(s.data) == 1 {
    s.data = nil
    return node
  }
  s.data = s.data[1:len(s.data)]
  return node
}
func (s *Queue) printSelf() {
  for i := 0; i < len(s.data); i++ {
    fmt.Print((*s.data[i]).Val)
  }
  fmt.Println("")
}