Leetcode刷题笔记-二叉树的遍历

前序遍历(python实现)

1. 递归实现

class Solution(object):
    def preorderTraversal(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        if root is None: return
        print(root.val)
        self.preorderTraversal(root.left)
        self.preorderTraversal(root.right)

root = TreeNode(1)
root.left, root.right = TreeNode(2), TreeNode(2)
root.left.left, root.right.right = TreeNode(3), TreeNode(3)
root.left.right, root.right.left = TreeNode(4), TreeNode(4)
solution = Solution()
s = solution.preorderTraversal(root)
print(s)
# 1 2 3 4 2 4 3 None

2. 迭代实现

class Solution(object):
    def preorderTraversal(self, root):
        path = []
        if root is None: return path
        stack = []
        stack.append(root)
        while stack:
            root = stack.pop()
            path.append(root.val)
            if root.right is not None:
                stack.append(root.right)
            if root.left is not None:
                stack.append(root.left)
        return path
root = TreeNode(1)
root.left, root.right = TreeNode(2), TreeNode(2)
root.left.left, root.right.right = TreeNode(3), TreeNode(3)
root.left.right, root.right.left = TreeNode(4), TreeNode(4)
solution = Solution()
s = solution.preorderTraversal(root)
print(s)        # [1, 2, 3, 4, 2, 4, 3]
# 1 2 3 4 2 4 3 None

3. Morris Traversal Solution

class Solution(object):
    def preorderTraversal(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        result, curr = [], root
        while curr:
            if curr.left is None:
                result.append(curr.val)
                curr = curr.right
            else:
                node = curr.left
                while node.right and node.right != curr:
                    node = node.right
                if node.right is None:
                    result.append(curr.val)
                    node.right = curr
                    curr = curr.left
                else:
                    node.right = None
                    curr = curr.right
        return result

中序遍历(python3实现)

1. 递归

class Solution(object):
    def inorderTraversal(self, root):
        if not root: return
        self.inorderTraversal(root.left)
        print(root.val)
        self.inorderTraversal(root.right)

2. 迭代

class Solution(object):
    def inorderTraversal(self, root):
        path = []
        if root is None: return path
        stack = []
        while stack or root is not None:
            if root is not None:
                stack.append(root)
                root = root.left
            else:
                root = stack.pop()
                path.append(root.val)
                root = root.right
        return path
root = TreeNode(1)
root.left, root.right = TreeNode(2), TreeNode(2)
root.left.left, root.right.right = TreeNode(3), TreeNode(3)
root.left.right, root.right.left = TreeNode(4), TreeNode(4)
solution = Solution()
s = solution.inorderTraversal(root)
print(s)        # [3, 2, 4, 1, 4, 2, 3]
# 3 2 4 1 4 2 3 None

3. morris traversal

遍历二叉树是以一定规则将二叉树中的结点排列成一个线性序列,得到二叉树中结点的先序序列、中序序列或后序序列。这实质上是对一个非线性结构进行线性化操作。使每个结点(除第一个和最后一个外)在这些线性序列中有且仅有一个直接前驱和直接后继。

当二叉链表作为存储结构时,只能找到结点的左右孩子信息 。而不能直接得到结点在任一序列中的前驱和后继信息,这种信息只有在遍历的动态过程中才能得到,为此引入线索二叉树来保存这些在动态过程中得到的有关前驱和后继的信息。

扫描二维码关注公众号,回复: 1645212 查看本文章

但是这边不使用线索二叉树,只是利用一些关于前驱和后继的特征进行遍历。有一些理论知识需要掌握,所以需要先了解一下线索二叉树。

参考博客:http://www.cnblogs.com/AnnieKim/archive/2013/06/15/morristraversal.html

步骤:

1. 如果当前节点的左孩子为空,则输出当前节点并将其右孩子作为当前节点。

2. 如果当前节点的左孩子不为空,在当前节点的左子树中找到当前节点在中序遍历下的前驱节点。

   a) 如果前驱节点的右孩子为空,将它的右孩子设置为当前节点。当前节点更新为当前节点的左孩子。

   b) 如果前驱节点的右孩子为当前节点,将它的右孩子重新设为空(恢复树的形状)。输出当前节点。当前节点更新为当前节点的右孩子。

3. 重复以上1、2直到当前节点为空。

每个没有右节点的Node要建1个辅助path,回到他来自的那个左节点的parent。然后第二次来到这个点的时候,要去掉这个Path。所以每个点都遍历了2次,时间上还是O(n)

和那个树状数组有点像,以每个左节点为中心。

class Solution(object):
    def inorderTraversal(self, root):
        result, curr = [], root
        while curr:
            if curr.left is None:
                result.append(curr.val)
                curr = curr.right
            else:
                node = curr.left
                while node.right and node.right != curr:  ### while循环主要实现的功能:在当前节点的左子树中找到当前节点在中序遍历下的前驱节点。
                    node = node.right
                ##### first time, need to add a path
                if node.right is None:
                    # result.append(curr.val)   ### pre-order
                    node.right = curr
                    curr = curr.left
                else:
                    result.append(curr.val)     ### in-order
                    node.right = None
                    curr = curr.right
        return result
root = TreeNode(1)
root.left, root.right = TreeNode(2), TreeNode(2)
root.left.left, root.right.right = TreeNode(3), TreeNode(3)
root.left.right, root.right.left = TreeNode(4), TreeNode(4)
# print(root.left.right.right)
solution = Solution()
s = solution.inorderTraversal(root)
print(s)        # [3, 2, 4, 1, 4, 2, 3]
# 3 2 4 1 4 2 3 None

未完,后序遍历。。。

猜你喜欢

转载自www.cnblogs.com/Joyce-song94/p/9194518.html