算法---树总结篇之深度遍历

1. 二叉树的深度

题目1:leetcode 104 给定一个二叉树,找出其最大深度

二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。说明: 叶子节点是指没有子节点的节点。

示例:给定二叉树 [3,9,20,null,null,15,7],返回它的最大深度 3

  3
/ \
9 20
/ \
15 7

思路1:树的先序(递归)

  • 终止条件:如果二叉树为空,则深度为0;
  • 递归体:如果不为空,分别求左子树的深度和右子树的深度,取最大的再加1

代码如下:

#最大深度
def maxDepth(root):
    """
    :type root: TreeNode
    :rtype: int
    """
    if root == None:
        return 0
    leftDepth = maxDepth(root.left) + 1
    rightDepth = maxDepth(root.right) + 1
    return leftDepth if leftDepth>rightDepth else rightDepth

  

思路2:图的深度遍历

  • 将树转换成图的邻接表形式
  • 遍历图的初始点的邻接点,找到所有的路径
  • 返回最长路径的长度

代码如下:

from collections import defaultdict
def maxDepth2(nodes):
    #输入:nodes [3,9,20,null,null,15,7]

    #由节点列表构造图的邻接表
    def define_graph(arr):
        neig_dict = defaultdict(list)
        for i in range(len(arr)):
            if arr[i] != None:
                if (2*i+1) <= len(arr)-1 and arr[2*i+1]:#如果左节点存在
                    neig_dict[arr[i]].append(arr[2*i+1])
                if (2*i+2) <= len(arr)-1 and arr[2*i+2]:#如果右节点存在
                    neig_dict[arr[i]].append(arr[2*i+2])
                if (i-1)//2 >= 0 and arr[(i-1)//2]:#左子树的父节点
                    neig_dict[arr[i]].append(arr[(i-1)//2])
                elif (i-2)//2 >= 0 and arr[(i-2)//2]:#右子树的父节点
                    neig_dict[arr[i]].append(arr[(i-2)//2])
        return neig_dict

    #遍历邻接表,返回一次遍历的长度
    def dfs(nei_dict,i,visit):
        for j in nei_dict[i]:
            if j not in visit:
                visit.add(j)
                dfs(neig_dict,j,visit)
        return len(visit)

    neig_dict = define_graph(nodes)
    init_node = nodes[0]#图的起始点
    visit = set()
    visit.add(init_node)
    max_len = 0
    for i in neig_dict[init_node]:#遍历初始点的所有邻接点
        visit.add(i)
        max_len = max(dfs(neig_dict,i,visit),max_len)
        print('visit',visit)
        visit = set()#每遍历完一条路径之后,都要重新定义visit
        visit.add(init_node)
    return max_len

res = maxDepth2([3,9,20,None,None,15,7])
print("最大深度",res)

  

思路3:层次遍历

第一个节点为第1层,后面每个节点的层数等于父节点的层数+1

计算有多少层,即为树的深度

def maxDepth_leverOrder(arr,arr_level):
    def levelOrder(arr,i,arr_lever):#i是当前节点是index
        #先序遍历树的每一个节点,当前节点的层数等于上一层加一
        if (i-1)//2 >= 0 and arr[(i-1)//2]:#左节点存在
            arr_lever[i] = arr_lever[(i-1)//2] + 1#等于父节点层数加一
        elif (i-1)//2 >= 0 and arr[(i-1)//2]:#右节点存在
            arr_lever[i] = arr_lever[(i-1)//2] + 1

    for i in range(1,len(arr)):#遍历除了根节点的其他节点
        if arr[i] == None:
            continue
        else:
            levelOrder(arr,i,arr_level)

if __name__ == '__main__':
    arr = [3,9,20,None,None,15,7]
    if len (arr) == 1:
        print(1)
    else:
        arr_level = defaultdict(int)
        arr_level[0] = 1  # 根节点为第一层

        print ('arr_level before',arr_level)
        maxDepth_leverOrder(arr,arr_level)
        print('arr_level after',arr_level)
        print('深度',max(arr_level.items(),key=lambda x:x[1]))

 

5表示该节点在list中的index值,3是该节点对应的层数

  

层次遍历计算树的深度的递归方

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值