一般遍历树的方式有前序遍历、中序遍历、后序遍历以及层序遍历四种。
顺序是相对于根节点而言的,前序遍历就是根节点在前,左孩子其次,右孩子最后。中序遍历的顺序就是左孩子,根节点,右孩子。后序遍历顺序就是左孩子,右孩子,根节点。层序遍历则是一层一层的遍历。除了层序遍历外,其他三种遍历方式采用递归很容易能写出来,这里主要实现这四种遍历方式的非递归实现方法。
非递归前序遍历
def preOrder(root):
if not root:
return []
stack = [root]
res = []
while stack:
root = stack.pop()
res.append(root.val)
if root.right:
stack.append(root.right)
if root.left:
stack.append(root.left)
return res
非递归中序遍历
由于中序遍历需要最先访问左孩子,因此需要一直遍历到左孩子结点为空的结点才进行访问,然后再访问右孩子。
def inOrder(root):
if not root:
return []
stack = []
res = []
while stack or root:
while root:
stack.append(root)
root = root.left
if stack:
root = stack.pop()
res.append(root.val)
root = root.right
return res
非递归后序遍历
后序遍历如果按很多网上其他的非递归遍历方法,感觉又复杂又难理解,因为后序遍历的遍历顺序是左孩子,右孩子,最后才是根节点。这里采用相反的方式,先访问根节点,再来是右孩子,最后左孩子。这样遍历完之后返回遍历结果的倒序,即是最终的结果。
def postOrder(root):
if not root:
return []
stack = []
res = []
while stack or root:
while root:
stack.append(root)
res.append(root.val)
root = root.right
if stack:
root = stack.pop()
root = root.left
return res[::-1]
非递归层序遍历
这里用到队列,当左孩子存在,则入队,右孩子存在,入队,每次取队首结点。
def levelOrder(root):
if not root:
return []
queue = [root]
res = []
while queue:
root = queue[0]
queue = queue[1:]
res.append(root.val)
if root.left:
queue.append(root.left)
if root.right:
queue.append(root.right)
return res