LeetCode 剑指Offer 数据结构之 树 总结 Part1

LeetCode 剑指Offer 数据结构之 树 总结 Part1

经典问题

1)遍历
2)树深度
3)重建树
4)对称树
5)子树匹配
6)二叉查找树

遍历问题

对应的题目是剑指 Offer 32 - I,剑指 Offer 32 - II,剑指 Offer 32 - III,剑指 Offer 34

DFS(一般采用递归) 深度优先的遍历

三种:
先序 根 左 右
(目前感觉用DFS先序走起比较多)

def preorderTraversal(root):
    """
    :type root: TreeNode
    :rtype: List[int]
    """
    if not root:
        return []
    return [root.val] + preorderTraversal(root.left) + preorderTraversal(root.right)

中序 左 根 右
(目前感觉中序用的多,主要在二叉查找树里,最大作用是把二叉查找树转化为一个有序队列)

def inorderTraversal(root):
    """
    :type root: TreeNode
    :rtype: List[int]
    """
    if not root:
        return []
    return inorderTraversal(root.left) + [root.val] + inorderTraversal(root.right)

后序 左 右 根

def lastorderTraversal(root):
    """
    :type root: TreeNode
    :rtype: List[int]
    """
    if not root:
        return []
    return lastorderTraversal(root.left) + lastorderTraversal(root.right) + [root.val]

总结:二叉树的递归遍历是自上而下的过程 出口为到叶子节点 连带了空树特例 比较好理解

BFS(一般利用队列) 广度优先的遍历

特点是层级明显,众多二叉树非递归解法的雏形套路……

def LevelOrder(node):
    if node == None:
        return
    stack = []
    stack.append(node)
    while stack != []:
        node = stack.pop(0)
        if node.left:
            stack.append(node.left)
        if node.right:
            stack.append(node.right)
        print(node.val)

以上为直接print 根据该print序列是无法还原树的,穿过叶子节点需要print null以还原树,后续会进行总结

该方式也比较容易改成按层,每层一个list的方式进行遍历,同时也很好做树的最大深度问题
‘’’
可以借助队列先进先出的特点,
①每次取对头节点的值放入结果中
②按照先序遍历每次先将根节点存入,再依次存入其左孩子右孩子(如果有的话)
以上两点在while循环中实现,直至队列长度为0
‘’’

def PrintTree(pRoot):
    '''
    按层从左到右打印tree
    :param pRoot:
    :return:
    '''
    if pRoot is None:
        return []
    if pRoot.left is None and pRoot.right is None:
        return [[pRoot.val]]
    stack = [pRoot]
    output = []
    while (stack):  # 下一层要打印的根
        temp = []
        for i in range(len(stack)):
            out_node = stack.pop(0)  # 先进先出
            temp.append(out_node.val)
            if out_node.left is not None:
                stack.append(out_node.left)  # 这个头结点的左孩子 放入下一层要打印的stack里
            if out_node.right is not None:
                stack.append(out_node.right)  # 这个头结点的右孩子 放入下一层要打印的stack里
        output.append(temp)
    return output

细节在于要遍历打印本层所有节点同时将这些节点的孩子节点放入队列,需要使用:range(len(stack)),因为队列pop后长度会变

下一部分将总结二叉树深度的相关问题

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值