对于二叉树的遍历,常规的递归或迭代都需要用到栈,不管是函数调用栈还是手动创建的栈。因此空间复杂度都是 O(n)。
如果要省掉栈的开销,将空间复杂度降低到 O(1),则需要借助二叉树中的叶子节点来保存临时信息。只要当前节点 cur 不为空,就一直循环:
- 如果当前节点 cur 的左子节点不存在,则输出 cur,并设置 cur = cur.right
- 否则,寻找当前节点中序遍历的前驱节点 prev
- 如果 prev.right 是空节点,表示这是头一次访问到这个节点,设置临时信息 prev.right = cur
- 否则,清除临时信息 prev.right = None,然后输出 cur,最后设置 cur = cur.right
- 只要当前节点 cur 不为空,继续第一步
# -*- coding: UTF-8 -*-
class TreeNode:
def __init__(self, val):
self.val = val
self.left = None
self.right = None
class Tree:
def __init__(self):
self.root = None
def show(self):
return
def construct(self, li = None):
if not li:
return None
tl = []
for i in li:
if i is None:
tl.append(None)
else:
tl.append(TreeNode(i))
for idx in range(len(li) / 2):
if idx * 2 + 1 < len(tl) and tl[idx * 2 + 1]:
tl[idx].left = tl[idx * 2 + 1]
if idx * 2 + 2 < len(tl) and tl[idx * 2 + 2]:
tl[idx].right = tl[idx * 2 + 2]
self.root = tl[0]
def inOrder(self, cur):
if not cur:
return
self.inOrder(cur.left)
print(cur.val)
self.inOrder(cur.right)
def inOrderMorrisTraversal(self, cur):
a = 1
while cur:
if not cur.left:
print(cur.val)
cur = cur.right
else:
prev = cur.left
while prev.right and prev.right != cur:
prev = prev.right
if not prev.right:
prev.right = cur
cur = cur.left
else:
prev.right = None
print(cur.val)
cur = cur.right
l = [2, 3, 4, 5, None, 7]
t = Tree()
t.construct(l)
print("in order:")
t.inOrder(t.root)
print("in order morris traversal:")
t.inOrderMorrisTraversal(t.root)