Leetcode-144 二叉树的前序遍历的三种方式-迭代、递归、莫里斯,Python实现

相关内容

  • leetcode144网址
  • Leetcode-94 二叉树的中序遍历
  • Leetcode-144 二叉树的前序遍历
  • Leercode-145 二叉树的后序遍历
  • 莫里斯算法python实现

给定一个二叉树,返回它的前序遍历。
Leetcode-144 二叉树的前序遍历的三种方式-迭代、递归、莫里斯,Python实现_第1张图片
具体的结题思路见代码注释

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
	'''
	迭代法
	迭代法维护了一个堆栈,以此记录了从前序中左右从高层根节点到底层叶子节点的顺序,
	并且根据中左右,在第一次访问根节点的时候就把结果输出
	记录的堆栈的目的是从底层叶子返回根节点然后到右子树上
	'''
    def preorderTraversal(self, root: TreeNode) -> List[int]:
        result = []
        stack = []
        current = root
        while stack or current:
            while current:
                result.append(current.val)
                stack.append(current)
                current = current.left
            current = stack.pop()
            current = current.right
        return result
	

	'''
	递归法
	递归法判断当前节点是否为空
	当不为空是依次按照中、左、右的顺讯进行遍历,其中中就直接输出
	'''
	def preorderTraversal(self, root: TreeNode) -> List[int]:
        result = []
        def _preorderTraversal(root):
            if root:
                result.append(root.val)
                _preorderTraversal(root.left)
                _preorderTraversal(root.right)
        _preorderTraversal(root)
        return result


	'''
	莫里斯算法
	莫里斯算法对于每一个节点将该节点的中序前驱节点(左子树上最右的叶子节点)的空右子树的内存指向自己
	作为从底层叶子节点返回高层根节点的途径。
	在迭代法中需要维护一个堆栈,作为从中到左,之后以此退栈实现从左子树回到根节点然后在进行向右子树的递归
	'''
    def preorderTraversal(self, root: TreeNode) -> List[int]:
        self.result = []
        current = root  # 当前节点设置为根节点
        while current:
            if not current.left:  # 前序遍历是中左右的顺序,当没有左子树时,直接输出值,并转到右子树上
                self.result.append(current.val)
                current = current.right
            else:  # 当存在左子树时,找到根节点的中序前驱节点,也就是左子树的最右的叶子
                pre = current.left
                while pre.right and pre.right!=current:  # 判断左子树的最右叶子的右子树(本来是空内存)是否为空
                    pre = pre.right
                if not pre.right:  
                	# 当右子树是空,说明该根节点是第一次被访问
                	# 按照前序 中左右,根节点第一次被访问时就应该输出
                	#
                	# 前序和中序遍历不一样的地方在于,中序遍历是左中右,是从中到左到中的时候才将根节点输出
                	# 所以中序遍历是在第二次访问节点是输出
                	#
                	# 第一次访问根节点时,将中序前驱节点的右子树空内存指向根节点
                	# 然后按照中左右的顺序,访问了根节点就需要左子树,将当前节点转向左子树,
                    self.result.append(current.val)
                    pre.right = current
                    current = current.left
                else:
                	# 此时中序前驱节点的右子树的本来是空的内存已经指向了根节点
                	# 说明当前的根节点,已经是从左子树访问完了又回到了根节点,第二次访问根节点了
                	# 此时就需要将中序前序节点的右子树的内存值为空,回到最初树的形状
                	# 然后当前节点转向右子树
                    pre.right = None
                    current = current.right
        return self.result

你可能感兴趣的:(算法及数据结构,刷题,python代码)