【二叉树】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)
发布了295 篇原创文章 · 获赞 158 · 访问量 101万+

猜你喜欢

转载自blog.csdn.net/kikajack/article/details/102882806