6.4 数据结构---树的深度
分类:
数据结构
一、最大深度
1.二叉树的最大深度 leetcode104
给定一个二叉树,找出其最大深度。 二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。 说明: 叶子节点是指没有子节点的节点。 示例: 给定二叉树 [ 3 , 9 , 20 ,null,null, 15 , 7 ], 3 / \ 9 20 / \ 15 7 返回它的最大深度 3 |
思路1:深度优先搜索(递归)
终止条件:如果二叉树为空,则深度为0;
递归体:如果不为空,分别求左子树的深度和右子树的深度,取最大的再加1
1 2 3 4 5 6 7 8 9 10 | 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:把树看做是图,用dfs求最长长度的路径
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | 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 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | 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) 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,3==> 树在列表中的index值,对应的深度 def level_Order_init(root): # 层次遍历的递归写法 def maxDepth_leverOrder_recur(level, result, node): if node: print ( 'level=%s,result长度=%s' % (level, len (result))) #level<len(result),说明有下一层,但是还没放数据 #level=len(result),说明有下一层且该层数据已经遍历完 if level = = len (result): #说明该层数据已经遍历完成,下一步要遍历下一层的数据 result.append([]) result[level].append(node.val) #该层 maxDepth_leverOrder_recur(level + 1 ,result,node.left) #左,下一层 maxDepth_leverOrder_recur(level + 1 ,result,node.right) #右,下一层 level,result = 0 ,[] maxDepth_leverOrder_recur(level,result,root) print ( '深度' , len (result)) return result L1 = TreeNode( 3 ) L2 = TreeNode( 9 ) L3 = TreeNode( 20 ) L4 = TreeNode( 15 ) L5 = TreeNode( 7 ) L1.left = L2 L1.right = L3 L2.left = None L2.right = None L3.left = L4 L3.right = L5 res = level_Order_init(L1) print (res) |
2.N叉树的最大深度 leetcode559
题目:给定一个N叉树,找到其最大深度。最大深度是指从根节点到最远叶子节点的最长路径上的节点总数
思路:二叉树求最大深度一样,只是由固定的左右子节点变成了一堆子节点,方法没变
- 递归,如果node为空,直接返回
- 遍历node的所有孩子节点,取最大值+1作为最大深度
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | class TreeNode: def __init__( self , val, children): self .val = val self .children = children def maxDepth(node): if node = = None : return 0 if not node.children: return 1 #计算所有孩子节点的深度最大值 # print('node.children',node.children) if len (node.children) > = 1 : this_child_maxdpth = [] for child in node.children: this_child_maxdpth.append(maxDepth(child) + 1 ) return max (this_child_maxdpth) L5 = TreeNode( 5 , None ) L6 = TreeNode( 6 , None ) L3 = TreeNode( 2 , None ) L4 = TreeNode( 5 , None ) L2 = TreeNode( 3 ,children = (L5,L6)) L1 = TreeNode( 1 ,children = (L2,L3,L4)) res = maxDepth(L1) print (res) |
二、最小深度
1.二叉树的最小深度 leetcode111
题目:给定一个二叉树,找出其最小深度。二叉树的最小深度为根节点到最近叶子节点的距离。
思路1:计算左子树和右子树深度的时候,判断是否等于0,如果等于0,说明该子树不存在,深度赋值为最大值。
思路2:判断左子树或右子树是否为空,若左子树为空,则返回右子树的深度,反之返回左子树的深度,如果都不为空,则返回左子树和右子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | class TreeNode: def __init__( self , x): self .val = x self .left = None self .right = None def minDepth(root): """ :type root: TreeNode :rtype: int """ if root = = None : return 0 # 若左子树为空,则返回右子树的深度,反之返回左子树的深度 if root.left = = None : return minDepth(root.right) + 1 if root.right = = None : return minDepth(root.left) + 1 #如果都不为空,则返回左子树和右子树深度的最小值 leftDepth = minDepth(root.left) + 1 rightDepth = minDepth(root.right) + 1 return leftDepth if leftDepth < rightDepth else rightDepth L1 = TreeNode( 3 ) L2 = TreeNode( 9 ) L3 = TreeNode( 20 ) L4 = TreeNode( 15 ) L5 = TreeNode( 7 ) L1.left = L2 L1.right = L3 L2.left = None L2.right = None L3.left = L4 L3.right = L5 res = minDepth(L1) print (res) |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现