對於二叉樹的遍歷,常規的遞歸或迭代都需要用到棧,不管是函數調用棧還是手動創建的棧。因此空間複雜度都是 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)