假设二叉树的定义如下:
class TreeNode():
def __init__(self, x):
self.val = x
self.left = None
self.right = None
考察利用非递归的方法遍历二叉树。
先序遍历
对于任何一个子树,打印当前子树根结点,用栈保存右子结点后直接跳转至左子结点,继续下一个子树循环。这样,当左子结点为空的时候,出栈并取出最近的右子结点即可实现先序遍历。
def preordertraverse(self, root):
nodes = []
if root is not None:
nodes.append(root)
while len(nodes) > 0:
tmp = nodes.pop()
while tmp is not None:
print(tmp.val, end=' ')
if tmp.right:
nodes.append(tmp.right)
tmp = tmp.left
中序遍历
首先左移至当前子树最左叶子结点,沿途将所有结点压入栈。遇到左子结点为空,出栈打印,并观察该元素是否有右子结点,有则压栈、右移并在新的子树中重复循环,无则继续出栈打印观察。当辅助栈为空时,遍历结束。
def inordertraverse(self, root):
nodes = []
if root is not None:
nodes.append(root)
tmp = root
while len(nodes) > 0:
while tmp.left is not None:
tmp = tmp.left
nodes.append(tmp)
tmp = nodes.pop()
print(tmp.val, end=' ')
if tmp.right:
tmp = tmp.right
nodes.append(tmp)
后序遍历
开始步骤类似中序遍历,首先要找到最底层的左叶子结点,在不断左移的过程中,需要依次保存当前子树的根结点和右子结点。当左子结点为空时,观察右子结点是否为空,若不为空压栈,重复循环;若为空出栈打印,并判断是否需要连续回溯弹出。
def post_order_traverse(self,root):
res = []
if root is None:
return res
nodes = [root]
while len(nodes) > 0:
node = nodes[-1]
while node.left is not None:
if node.right is not None:
nodes.append(node.right)
node = node.left
nodes.append(node)
if node.right is not None:
node = node.right
nodes.append(node)
else:
node = nodes.pop()
res.append(node.val)
while len(nodes) > 0 and (node is nodes[-1].right or node is nodes[-1].left):
node = nodes.pop()
res.append(node.val)
return res