和普通的用stack的方法去处理二叉树的非递归遍历,Morris算法在空间上有优化。stack方法的空间复杂度是O(N), 但Morris是O(1)
Morris的核心思想是用前驱点和当前点来建立一个通路。Morris用了线索二叉树的思想,用叶子节点左右空指针指向某种遍历顺序的前驱结点和当前结点来实现。其中前序和中序思想完全相同,只是当前节点什么时候输出不同。
一个写的很好的微博:
基本写代码的流程是:
http://chengfeng96.com/blog/2017/11/12/%E5%88%A9%E7%94%A8Morris-Traversal%E6%96%B9%E6%B3%95%E9%81%8D%E5%8E%86%E4%BA%8C%E5%8F%89%E6%A0%91/
在当前节点不为空的情况下
if: 如果当前节点的左儿子为空,输出当前节点,同时当前节点等于它的右儿子(不用担心右儿子为空,因为prev第一次会改变叶子的右儿子空的指向)
else: 让前驱结点等于当前节点的左儿子
如果前驱结点的右儿子不是空+前驱节点的右儿子不等于当前节点,前驱节点等于右儿子
if: 前驱节点的右儿子为空,前驱结点的右儿子等于当前节点,(如果是前序遍历,这个时候输出当前节点),当前节点等于当前节点的左儿子。
else:前驱结点的右儿子等于空(这是为了恢复原始的书结构),(如果是中序遍历,这个时候输出当前节点),当前节点等于当前节点的右儿子。
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
前序遍历
""" Definition of TreeNode: class TreeNode: def __init__(self, val): self.val = val self.left, self.right = None, None """ class Solution: """ @param root: A Tree @return: Preorder in ArrayList which contains node values. """ def preorderTraversal(self, root): # write your code here if root is None: return [] pre_order = [] cur = root prev = None while cur is not None: if cur.left is None: pre_order.append(cur.val) cur = cur.right else: prev = cur.left while prev.right is not None and prev.right != cur: prev = prev.right if prev.right is None: prev.right = cur pre_order.append(cur.val) cur = cur.left else: prev.right = None cur = cur.right return pre_order
中序遍历:
""" Definition of TreeNode: class TreeNode: def __init__(self, val): self.val = val self.left, self.right = None, None """ class Solution: """ @param root: A Tree @return: Inorder in ArrayList which contains node values. """ def inorderTraversal(self, root): # write your code here if root is None: return [] in_order = [] cur = root prev = None while cur is not None: if cur.left is None: in_order.append(cur.val) cur = cur.right else: prev = cur.left while prev.right is not None and prev.right != cur: prev = prev.right if prev.right is None: prev.right = cur cur = cur.left else: prev.right = None in_order.append(cur.val) cur = cur.right return in_order