zoukankan      html  css  js  c++  java
  • 6.4 数据结构---树的深度

    一、最大深度

    1.二叉树的最大深度 leetcode104

    给定一个二叉树,找出其最大深度。
    二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。
    说明: 叶子节点是指没有子节点的节点。
    示例:
    给定二叉树 [3,9,20,null,null,15,7],
        3
       / 
      9  20
        /  
       15   7
    返回它的最大深度 3
    

      

    思路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:把树看做是图,用dfs求最长长度的路径

    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:层次遍历,计算有多少层,即为树的深度

    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作为最大深度
    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:判断左子树或右子树是否为空,若左子树为空,则返回右子树的深度,反之返回左子树的深度,如果都不为空,则返回左子树和右子

    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)
    

      

  • 相关阅读:
    UVa OJ 148 Anagram checker (回文构词检测)
    UVa OJ 134 LoglanA Logical Language (Loglan逻辑语言)
    平面内两条线段的位置关系(相交)判定与交点求解
    UVa OJ 130 Roman Roulette (罗马轮盘赌)
    UVa OJ 135 No Rectangles (没有矩形)
    混合函数继承方式构造函数
    html5基础(第一天)
    js中substr,substring,indexOf,lastIndexOf,split等的用法
    css的textindent属性实现段落第一行缩进
    普通的css普通的描边字
  • 原文地址:https://www.cnblogs.com/nxf-rabbit75/p/11675906.html
Copyright © 2011-2022 走看看