刷题---树篇---94. 二叉树的中序遍历(go,python实现)

99 篇文章 0 订阅
30 篇文章 1 订阅

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

难度:中等

示例:

输入: [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
}

python非递归实现:

class Solution:
    def inorderTraversal(self, root: TreeNode) -> List[int]:
        nums = []
        node = []
        if root == None:
            return nums

        while root != None or len(node) != 0:
            while root != None:
                node.append(root)
                root = root.left

            root = node.pop()
            nums.append(root.val)
            root = root.right

        return nums

我对这一解法的理解是:

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

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

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

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

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

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

 

如图所示:

方法二:

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
}

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值