【二叉樹】O(1)空間複雜度的Morris遍歷

對於二叉樹的遍歷,常規的遞歸或迭代都需要用到棧,不管是函數調用棧還是手動創建的棧。因此空間複雜度都是 O(n)。

如果要省掉棧的開銷,將空間複雜度降低到 O(1),則需要藉助二叉樹中的葉子節點來保存臨時信息。只要當前節點 cur 不爲空,就一直循環:

  1. 如果當前節點 cur 的左子節點不存在,則輸出 cur,並設置 cur = cur.right
  2. 否則,尋找當前節點中序遍歷的前驅節點 prev
    1. 如果 prev.right 是空節點,表示這是頭一次訪問到這個節點,設置臨時信息 prev.right = cur
    2. 否則,清除臨時信息 prev.right = None,然後輸出 cur,最後設置 cur = cur.right
  3. 只要當前節點 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)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章