二叉树前序、中序、后续遍历, 非递归形式(魔改版——超简单, 和递归方式的思考形式一致)

前言

二叉树是以递归的形式定义的, 所以用递归形式访问它节点的内容会非常简单。 但是, 如果用非递归形式来该怎么做呢? 可以看到网上的非递归形式都非常的复杂而且还不好想, 这里总结一种较为简单的方式, 如果有用点个赞哈哈哈哈。。。本文是根据bobi听了慕课网波比老师的讲述写的

题目链接

前序遍历:144. 二叉树的前序遍历 - 力扣(LeetCode) (leetcode-cn.com)

中序遍历:94. 二叉树的中序遍历 - 力扣(LeetCode) (leetcode-cn.com)

后续遍历:145. 二叉树的后序遍历 - 力扣(LeetCode) (leetcode-cn.com)

递归版(递归版就直接上代码, 相信大家也都会)

前序遍历

class Solution:
    def preorderVisit(self, root):
        if root:
            self.res.append(root.val)
            self.preorderVisit(root.left)
            self.preorderVisit(root.right)

    def preorderTraversal(self, root):
        self.res = []
        self.preorderVisit(root)
        return self.res

中序遍历 

class Solution:
    def Visit(self, root):
        if root:
            self.Visit(root.left)
            self.res.append(root.val)
            self.Visit(root.right)

    def inorderTraversal(self, root):
        self.res = []
        self.Visit(root)
        return self.res

后序遍历

class Solution:
    def Order(self, root):
        if root:
            self.Order(root.left)
            self.Order(root.right)
            self.res.append(root.val)

    def postorderTraversal(self, root):
        self.res = []
        self.Order(root)
        return self.res

非递归版

分析

递归版好写的主要原因是: 在访问节点时, 比如前序, 就是先遍历该节点内容, 然后再取访问该节点的左右子树, 然后就根据定义先将节点内容遍历(这里遍历后保存), 然后再用函数分别去访问左右节点即可。 怎么说怎么写, 说的是什么顺序, 写的就是什么顺序!

但是非递归版不同啊! 非递归众所周知要用到栈与迭代, 可谓非常麻烦, 特别是后序遍历, 这里就根据理解写出相同的三个遍历的非递归版本!使其的思考方式与非递归版本差不多!改进方法就是添加了一个访问标志位visited, 后面再来解释整个逻辑吧


前序遍历 

class Solution:
    def preorderTraversal(self, root):
        stack = []
        res = []

        if root == None:
            return res

        stack.append(root)

        while len(stack) > 0:
            cur = stack.pop()
            res.append(cur.val)

            if cur.right != None:
                stack.append(cur.right)

            if cur.left != None:
                stack.append(cur.left)

        return res

中序遍历

class Solution:
    def inorderTraversal(self, root):
        stack = []
        res = []

        if root == None:
            return res

        root.visited = False     # 代表是否已经加入过栈中
        stack.append(root)
        while len(stack) != 0:
            cur = stack.pop()

            if cur.visited:
                res.append(cur.val)

            else:
                if cur.right != None:
                    cur.right.visited = False
                    stack.append(cur.right)

                stack.append(cur)         # 将当前元素又放进去, 因为还没到遍历其val的时候

                if cur.left != None:
                    cur.left.visited = False
                    stack.append(cur.left)

                cur.visited = True

        return res

后序遍历

class Solution:
    def postorderTraversal(self, root):
        stack = []
        res = []

        if root == None:
            return res

        root.visited = False
        stack.append(root)

        while len(stack) != 0:
            cur = stack.pop()
            if cur.visited:
                res.append(cur.val)

            else:
                cur.visited = True
                stack.append(cur)     # 最后访问, 最先加入

                if cur.right != None:
                    cur.right.visited = False
                    stack.append(cur.right)

                if cur.left != None:
                    cur.left.visited = False
                    stack.append(cur.left)

        return res

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

索利亚噶通

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值