二叉树的深度优先递归遍历,很直观简洁,然而改成循环遍历之后,就有点复杂了,先序中序后序遍历的代码结构又各不相同。所以本文尝试了用一个通用的方式实现3种次序的循环遍历。没有太大意义,只是一个递归程序如何改成循环的思路。
from typing import List
from enum import Enum
#定义遍历次序的枚举
class Order(Enum):
#先序遍历
PRE = 1
#中序遍历
IN = 2
#后序遍历
POST = 3
class Node:
def __init__(self):
self.left = None
self.right = None
self.val = 0
def __str__(self):
return str(self.val)
#从数组构造二叉树
@staticmethod
def build_from_array(ar: List[int]):
n = len(ar)
def build(idx):
l, r = (idx + 1) * 2 - 1, (idx + 1) * 2
node = Node()
node.val = ar[idx]
if l < n:
node.left = build(l)
if r < n:
node.right = build(r)
return node
return build(0)
#二叉树广度遍历,还原数组
def bfs(self) -> List[int]:
q=[self]
res = []
while q != []:
n = q.pop(0)
res.append(n.val)
if n.left is not None:
q.append(n.left)
if n.right is not None:
q.append(n.right)
return res
#深度优先递归遍历
def dfs_recursive(self, order:Order) -> List[int]:
res = []
def dfs(node):
if node is None:
return
if order == Order.PRE:
res.append(node.val)
dfs(node.left)
if order == Order.IN:
res.append(node.val)
dfs(node.right)
if order == Order.POST:
res.append(node.val)
dfs(self)
return res
#深度优先循环遍历
def dfs_iterate(self, order:Order) -> List[int]:
q=[self]
res = []
while q != []:
node = q.pop()
if isinstance(node, int):
res.append(node)
else:
#根据递归版的方法改造,方法体被递归调用分隔成几部分
#每一部分按照从下到上的顺序,压入模拟栈
if order == Order.POST:
q.append(node.val)
if node.right is not None:
q.append(node.right)
if order == Order.IN:
q.append(node.val)
if node.left is not None:
q.append(node.left)
if order == Order.PRE:
q.append(node.val)
return res
#先序遍历的优化
def dfs_iterate_preorder(self) -> List[int]:
q=[self]
res = []
while q != []:
node = q.pop()
if node.right is not None:
q.append(node.right)
if node.left is not None:
q.append(node.left)
res.append(node.val)
return res
node = Node.build_from_array([0, 1, 2, 3, 4, 5, 6])
for o in Order:
# 验证递归和循环遍历结果
assert node.dfs_recursive(o) == node.dfs_iterate(o)