前言
二叉树是以递归的形式定义的, 所以用递归形式访问它节点的内容会非常简单。 但是, 如果用非递归形式来该怎么做呢? 可以看到网上的非递归形式都非常的复杂而且还不好想, 这里总结一种较为简单的方式, 如果有用点个赞哈哈哈哈。。。本文是根据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