算法练习Day12 (Leetcode/Python-二叉树)

二叉树基本知识:

满二叉树:如果一棵二叉树只有度为0的结点和度为2的结点,并且度为0的结点在同一层上,则这棵二叉树为满二叉树。深度为k,有2^k-1个节点的二叉树。

完全二叉树:除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层(h从1开始),则该层包含 1~ 2^(h-1) 个节点。

二叉搜索树:有数值,二叉搜索树是一个有序树

  • 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
  • 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
  • 它的左、右子树也分别为二叉排序树

平衡二叉搜索树:又被称为AVL(Adelson-Velsky and Landis)树,且具有以下性质:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。

顺序存储二叉树:如果父节点的数组下标是 i,那么它的左孩子就是 i * 2 + 1,右孩子就是 i * 2 + 2。

链式存储二叉树:通过指针把分布在各个地址的节点串联一起。

前序遍历preorder:中->左->右

中序遍历inorder:左->中->右

后序遍历postorder:左->右->中


二叉树遍历

145. Binary Tree Postorder Traversal

94. Binary Tree Inorder Traversal


144. Binary Tree Preorder Traversal

递归法:

# 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]:
        # Traverse order: middle->left->right
        if not root: # if the tree is empty 
            return []
        else:
            left = self.preorderTraversal(root.left)
            right = self.preorderTraversal(root.right)
        return [root.val] + left + right

Tips:对于递归法,中序遍历后续遍历只需要修改return的顺序即可。

迭代法:

preorder:

# 迭代 Iteration
class Solution:
    def preorderTraversal(self, root: Optional[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 

inorder:

要先记最左的元素,所以在找到最左的元素前之前经过的元素先push到stack里存起来。

# 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 inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        if not root:
            return []
        stack = []
        result = []
        cur = root
        while cur or stack: 
            if cur: # 找到最左的元素,在此之前,持续向stack内push父节点
                stack.append(cur)
                cur = cur.left 
            else: # 当当前节点没有叶左节点时,开始pop stack的值
                cur = stack.pop() # 把stack的元素pop出
                result.append(cur.val) 
                cur = cur.right # 如果当前节点入栈后有右节点,即将右节点push进stack里,接下来会再pop出,append进result里。
        return result 

 postorder

前序遍历是中左右,后序遍历是左右中。那么可以先取中右左,然后reverse。中左右的写法和前序类似。

# 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]:
        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]

reference:

代码随想录

  • 10
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值