day14| 94.二叉树的中序遍历;144.二叉树的前序遍历;145.二叉树的后序遍历

94. 二叉树的中序遍历

 

思路:

1. 找出重复的子问题

  这个重复的子问题是:先遍历左子树、再取根节点、最后遍历右子树

2. 确定终止条件

  当节点为空是,返回

 

代码如下:

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

    def inOrder(self, root:TreeNode, res):
        if root == None:
            return
        self.inOrder(root.left, res)
        res.append(root.val)
        self.inOrder(root.right, res)

    def inorderTraversal(self, root: TreeNode) -> List[int]:
        res = []
        self.inOrder(root, res)
        return res

 

迭代解法

1. 初始化时先把中节点放入栈中,直接取出中节点的值,加入result中,中节点弹出栈

2. 并且让右孩子先入栈,左孩子后入栈

3. 只要stack不为空,就一直迭代进行

 

代码如下:

# 前序遍历-迭代-LC144_二叉树的前序遍历
class Solution:
    def preorderTraversal(self, root: TreeNode) -> List[int]:
        # 根结点为空则返回空列表
        if not root:
            return []
        stack = [root]
        result = []
        while stack:
            node = stack.pop()
            # 中结点先处理
            result.append(node.val)
            # 右孩子先入栈
            if node.right:
                stack.append(node.right)
            # 左孩子后入栈
            if node.left:
                stack.append(node.left)
        return result

 

 

144. 二叉树的前序遍历

 

同上一题,改一改append和函数递归调用的顺序即可

 

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        res=[]
        self.midOrder(root,res)
        return res
    

    def midOrder(self,root:TreeNode,res):
        if root == None:
            return
        res.append(root.val)
        self.midOrder(root.left,res)
        self.midOrder(root.right,res)

 

迭代遍历

1. 先访问到最底层左子树节点

2. 到达最底层,再进行一次cur=cur.left,下一次进入循环时,cur=None,就进入else语句,开始取值进入result

3. cur=stack.pop(),一开始cur为最左最底层的节点,取节点的val值

4. cur=cur.right,这为空,在下一个循环中,便执行cur=stack.pop()语句,便可以成功取到最左最底层节点的父节点的值;

5. 再往后cur=cur.right,又能取到最底层最前面一个的右节点,取得相应的值

6. 随后不断回退,实现迭代

 

代码如下:

# 中序遍历-迭代-LC94_二叉树的中序遍历
class Solution:
    def inorderTraversal(self, root: TreeNode) -> List[int]:
        if not root:
            return []
        stack = []  # 不能提前将root结点加入stack中
        result = []
        cur = root
        while cur or stack:
            # 先迭代访问最底层的左子树结点
            if cur:     
                stack.append(cur)
                cur = cur.left        
            # 到达最左结点后处理栈顶结点    
            else:        
                cur = stack.pop()
                result.append(cur.val)
                # 取栈顶元素右结点
                cur = cur.right    
        return result

 

 

 

145. 二叉树的后序遍历

 

同样,改一改顺序即可

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        res=[]
        self.postOrder(root,res)
        return res
    

    def postOrder(self,root:TreeNode,res):
        if root == None:
            return
        self.postOrder(root.left,res)
        self.postOrder(root.right,res)
        res.append(root.val)

 

迭代遍历:

稍微修改前序迭代遍历代码即可

 

代码如下:

# 后序遍历-迭代-LC145_二叉树的后序遍历
class Solution:
    def postorderTraversal(self, root: TreeNode) -> List[int]:
        if not root:
            return []
        stack = [root]
        result = []
        while stack:
            node = stack.pop()
            # 中结点先处理
            result.append(node.val)
            # 左孩子先入栈
            if node.left:
                stack.append(node.left)
            # 右孩子后入栈
            if node.right:
                stack.append(node.right)
        # 将最终的数组翻转
        return result[::-1]

 

 

统一迭代

 

将访问的节点和处理节点都放入栈中,但是处理的节点后面会跟一个空指针作为标记

 

代码如下:

# 前序遍历
class Solution:
    def preorderTraversal(self, root: TreeNode) -> List[int]:
        result = []
        st= []
        if root:
            st.append(root)
        while st:
            node = st.pop()
            if node != None:
                if node.right: #
                    st.append(node.right)
                if node.left: #
                    st.append(node.left)
                st.append(node) #
                st.append(None)
            else:
                node = st.pop()
                result.append(node.val)
        return result

# 中序遍历
class Solution:
    def inorderTraversal(self, root: TreeNode) -> List[int]:
        result = []
        st = []
        if root:
            st.append(root)
        while st:
            node = st.pop()
            if node != None:
                if node.right: #添加右节点(空节点不入栈)
                    st.append(node.right)
                
                st.append(node) #添加中节点
                st.append(None) #中节点访问过,但是还没有处理,加入空节点做为标记。
                
                if node.left: #添加左节点(空节点不入栈)
                    st.append(node.left)
            else: #只有遇到空节点的时候,才将下一个节点放进结果集
                node = st.pop() #重新取出栈中元素
                result.append(node.val) #加入到结果集
        return result


# 后序遍历
class Solution:
    def postorderTraversal(self, root: TreeNode) -> List[int]:
        result = []
        st = []
        if root:
            st.append(root)
        while st:
            node = st.pop()
            if node != None:
                st.append(node) #
                st.append(None)
                
                if node.right: #
                    st.append(node.right)
                if node.left: #
                    st.append(node.left)
            else:
                node = st.pop()
                result.append(node.val)
        return result

 

posted @ 2023-04-02 12:54  blueCP1999  阅读(27)  评论(0)    收藏  举报