欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

刷题---树篇---94. 二叉树的中序遍历

程序员文章站 2024-01-11 17:08:16
...

给定一个二叉树,返回它的中序 遍历。

难度:中等

示例:

输入: [1,null,2,3]
   1
    \
     2
    /
   3

输出: [1,3,2]
进阶: 递归算法很简单,你可以通过迭代算法完成吗?

———————————————————————————————————————————————————————

这本应该是一道基础题,基础的中序遍历算法。但是题目给了个要求,用迭代完成,这应该就是本题为中等难度的原因。

类似题:刷题---树篇---144. 二叉树的前序遍历

刷题---树篇---145. 二叉树的后序遍历

 

go递归版本:

func inorderTraversal(root *TreeNode) []int {
    res := make([]int,0)
    if root == nil {
        return res
    }

    Run(root,&res)
    return res
}

func Run(root *TreeNode, num *[]int) {
    if root == nil {
        return 
    }

    Run(root.Left,num)
    *num = append(*num,root.Val)
    Run(root.Right,num)
}

go非递归版本:

func inorderTraversal(root *TreeNode) []int {
    res := make([]int,0)
    if root == nil {
        return res
    }

    //手动维护一个栈
    stack := make([]*TreeNode,0)
    k := root
   
    for len(stack) != 0 || k != nil{  
        //若此时节点为nil,则不入栈
        //否则入栈
        for k != nil {
            stack = append(stack,k)
            k = k.Left
        }
        //出栈操作
        k = stack[len(stack)-1]
        stack = stack[:len(stack)-1]
        res = append(res,k.Val)
        //按照中序遍历原则,左-中-右
        //有右则入右
        k = k.Right
    }

    return res
}

我对这一解法的理解是:

按照中序遍历原则,左-中-右,则对于某一节点的入栈规则为:

先入自己,再入左子树,再入右子树。

当某一节点存在右子节点的时候,采取的方法是将右子节点入栈,作为下次循环的栈顶再进行处理。

在循环条件的选择:for len(stack) != 0 || k != nil

当栈为空且此时的节点为空时则结束循环,因为此时没有任何值得处理的节点。

换句话说,只有栈中有节点,则必须处理栈中的节点,只要节点k不为空,则必须处理节点k。

 

如图所示:

刷题---树篇---94. 二叉树的中序遍历

刷题---树篇---94. 二叉树的中序遍历

方法二:

func inorderTraversal(root *TreeNode) []int {
    stack := make([]*TreeNode,0)
    res := make([]int,0)
    if root == nil {
        return res
    }

    push(&stack,root)

    for len(stack) != 0 {
        for root.Left != nil {
            push(&stack,root.Left)
            root = root.Left
        }

        root,stack = pop(stack)
        root.Left = nil
        res = append(res,root.Val)

        if root.Right != nil {
            push(&stack,root.Right)
            root = root.Right
        } 
        
    }

    return res
}

func push(stack *[]*TreeNode,t *TreeNode) {
    *stack = append(*stack,t)
}
func pop(stack []*TreeNode) (*TreeNode,[]*TreeNode) {
    t := stack[len(stack)-1]
    stack = stack[:len(stack)-1]
    return t,stack
}