📌  相关文章
📜  给定二叉树每个节点的子树深度总和

📅  最后修改于: 2021-04-17 14:24:26             🧑  作者: Mango

给定一个由N个节点组成的二叉树,任务是查找给定二叉树中所有子树节点的深度之和。

例子:

天真的方法:最简单的方法是遍历树,并针对每个节点,递归地计算该节点的所有节点的深度之和,并打印得出的最终和。

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
using namespace std;
 
// Binary tree node
class TreeNode {
public:
    int data;
    TreeNode* left;
    TreeNode* right;
};
 
// Function that allocates a new
// node with data and NULL to its
// left and right pointers
TreeNode* newNode(int data)
{
    TreeNode* Node = new TreeNode();
    Node->data = data;
    Node->left = NULL;
    Node->right = NULL;
 
    // Return the node
    return (Node);
}
 
// Function to find the sum of depths of
// all nodes in subtree of the current node
int sumofdepth(TreeNode* root, int d)
{
    // IF NULL node then return 0
    if (root == NULL)
        return 0;
 
    // Recursivly find the sum of
    // depths of all nodes in the
    // left and right subtree
    return d + sumofdepth(root->left, d + 1)
           + sumofdepth(root->right, d + 1);
}
 
// Function to calculate the sum
// of depth of all the subtrees
int sumofallsubtrees(TreeNode* root)
{
    // if root is NULL return 0
    if (root == NULL)
        return 0;
 
    // Find the total depth sum of
    // current node and recursively
    return sumofdepth(root, 0)
           + sumofallsubtrees(root->left)
           + sumofallsubtrees(root->right);
}
 
// Driver Code
int main()
{
    // Given Tree
    TreeNode* root = newNode(1);
    root->left = newNode(2);
    root->right = newNode(3);
    root->left->left = newNode(4);
    root->left->right = newNode(5);
    root->right->left = newNode(6);
    root->right->right = newNode(7);
    root->left->left->left = newNode(8);
    root->left->left->right = newNode(9);
 
    // Function Call
    cout << sumofallsubtrees(root);
 
    return 0;
}


Java
// Java program for the above approach
class GFG{
 
// Binary tree node
static class TreeNode
{
    int data;
    TreeNode left, right;
}
 
// Function that allocates a new
// node with data and NULL to its
// left and right pointers
static TreeNode newNode(int data)
{
    TreeNode Node = new TreeNode();
    Node.data = data;
    Node.left = Node.right = null;
    return (Node);
}
 
// Function to find the sum of depths of
// all nodes in subtree of the current node
static int sumofdepth(TreeNode root, int d)
{
     
    // If NULL node then return 0
    if (root == null)
        return 0;
         
    // Recursivly find the sum of
    // depths of all nodes in the
    // left and right subtree
    return d + sumofdepth(root.left, d + 1) +
              sumofdepth(root.right, d + 1);
}
 
// Function to calculate the sum
// of depth of all the subtrees
static int sumofallsubtrees(TreeNode root)
{
     
    // If root is NULL return 0
    if (root == null)
        return 0;
 
    // Find the total depth sum of
    // current node and recursively
    return sumofdepth(root, 0) +
           sumofallsubtrees(root.left) +
           sumofallsubtrees(root.right);
}
 
// Driver Code
public static void main(String[] args)
{
     
    // Given Tree
    TreeNode root = newNode(1);
    root.left = newNode(2);
    root.right = newNode(3);
    root.left.left = newNode(4);
    root.left.right = newNode(5);
    root.right.left = newNode(6);
    root.right.right = newNode(7);
    root.left.left.left = newNode(8);
    root.left.left.right = newNode(9);
     
    // Function Call
    System.out.println(sumofallsubtrees(root));
}
}
 
// This code is contributed by Dharanendra L V


Python3
# Python3 program for the above approach
 
# Binary tree node
class TreeNode:
     
    def __init__(self, data):
         
        self.data = data
        self.left = None
        self.right = None
 
# Function to find the sum of depths of
# all nodes in subtree of the current node
def sumofdepth(root, d):
     
    # IF None node then return 0
    if (root == None):
        return 0
 
    # Recursivly find the sum of
    # depths of all nodes in the
    # left and right subtree
    return (d + sumofdepth(root.left, d + 1) +
                sumofdepth(root.right, d + 1))
 
# Function to calculate the sum
# of depth of all the subtrees
def sumofallsubtrees(root):
     
    # If root is None return 0
    if (root == None):
        return 0
 
    # Find the total depth sum of
    # current node and recursively
    return (sumofdepth(root, 0) + sumofallsubtrees(root.left) +
                                  sumofallsubtrees(root.right))
 
# Driver Code
if __name__ == '__main__':
     
    # Given Tree
    root = TreeNode(1)
    root.left = TreeNode(2)
    root.right = TreeNode(3)
    root.left.left = TreeNode(4)
    root.left.right = TreeNode(5)
    root.right.left = TreeNode(6)
    root.right.right = TreeNode(7)
    root.left.left.left = TreeNode(8)
    root.left.left.right = TreeNode(9)
 
    # Function Call
    print(sumofallsubtrees(root))
 
# This code is contributed by ipg2016107


C#
// C# program for the above approach
using System;
public class GFG{
 
// Binary tree node
class TreeNode
{
    public int data;
    public TreeNode left, right;
}
 
// Function that allocates a new
// node with data and NULL to its
// left and right pointers
static TreeNode newNode(int data)
{
    TreeNode Node = new TreeNode();
    Node.data = data;
    Node.left = Node.right = null;
    return (Node);
}
 
// Function to find the sum of depths of
// all nodes in subtree of the current node
static int sumofdepth(TreeNode root, int d)
{
     
    // If NULL node then return 0
    if (root == null)
        return 0;
         
    // Recursivly find the sum of
    // depths of all nodes in the
    // left and right subtree
    return d + sumofdepth(root.left, d + 1) +
              sumofdepth(root.right, d + 1);
}
 
// Function to calculate the sum
// of depth of all the subtrees
static int sumofallsubtrees(TreeNode root)
{
     
    // If root is NULL return 0
    if (root == null)
        return 0;
 
    // Find the total depth sum of
    // current node and recursively
    return sumofdepth(root, 0) +
           sumofallsubtrees(root.left) +
           sumofallsubtrees(root.right);
}
 
// Driver Code
public static void Main(String[] args)
{
     
    // Given Tree
    TreeNode root = newNode(1);
    root.left = newNode(2);
    root.right = newNode(3);
    root.left.left = newNode(4);
    root.left.right = newNode(5);
    root.right.left = newNode(6);
    root.right.right = newNode(7);
    root.left.left.left = newNode(8);
    root.left.left.right = newNode(9);
     
    // Function Call
    Console.WriteLine(sumofallsubtrees(root));
}
}
 
// This code is contributed by shikhasingrajput


C++
// C++ program for the above approach
#include 
using namespace std;
 
// Binary tree node
class TreeNode {
public:
    int data;
    TreeNode* left;
    TreeNode* right;
};
 
// Function to allocate a new
// node with the given data and
// NULL in its left and right pointers
TreeNode* newNode(int data)
{
    TreeNode* Node = new TreeNode();
    Node->data = data;
    Node->left = NULL;
    Node->right = NULL;
 
    return (Node);
}
 
// DFS function to calculate the sum
// of depths of all subtrees depth sum
pair sumofsubtree(TreeNode* root,
                            int& ans)
{
    // Store total number of node in
    // its subtree and total sum of
    // depth in its subtree
    pair p = make_pair(1, 0);
 
    // Check if left is not NULL
    if (root->left) {
 
        // Call recursively the DFS
        // function for left child
        pair ptemp
            = sumofsubtree(root->left, ans);
 
        // Increment the sum of depths
        // by ptemp.first+p.temp.first
        p.second += ptemp.first
                    + ptemp.second;
 
        // Increment p.fisrt by count
        // of noded in left subtree
        p.first += ptemp.first;
    }
 
    // Check if right is not NULL
    if (root->right) {
 
        // Call recursively the DFS
        // function for right child
        pair ptemp
            = sumofsubtree(root->right, ans);
 
        // Increment the sum of depths
        // by ptemp.first+p.temp.first
        p.second += ptemp.first
                    + ptemp.second;
 
        // Increment p.fisrt by count of
        // nodes in right subtree
        p.first += ptemp.first;
    }
 
    // Increment the result by total
    // sum of depth in current subtree
    ans += p.second;
 
    // Return p
    return p;
}
 
// Driver Code
int main()
{
    // Given Tree
    TreeNode* root = newNode(1);
    root->left = newNode(2);
    root->right = newNode(3);
    root->left->left = newNode(4);
    root->left->right = newNode(5);
    root->right->left = newNode(6);
    root->right->right = newNode(7);
    root->left->left->left = newNode(8);
    root->left->left->right = newNode(9);
 
    int ans = 0;
 
    sumofsubtree(root, ans);
 
    // Print the result
    cout << ans;
 
    return 0;
}


Java
// Java program for the above approach
import java.util.*;
class GFG
{
    static int ans;
    static class pair
    {
        int first, second;
        public pair(int first, int second) 
        {
            this.first = first;
            this.second = second;
        }   
    }
   
// Binary tree node
static class TreeNode
{
    int data;
    TreeNode left;
    TreeNode right;
};
 
// Function to allocate a new
// node with the given data and
// null in its left and right pointers
static TreeNode newNode(int data)
{
    TreeNode Node = new TreeNode();
    Node.data = data;
    Node.left = null;
    Node.right = null;
    return (Node);
}
 
// DFS function to calculate the sum
// of depths of all subtrees depth sum
static pair sumofsubtree(TreeNode root)
{
   
    // Store total number of node in
    // its subtree and total sum of
    // depth in its subtree
    pair p = new pair(1, 0);
 
    // Check if left is not null
    if (root.left != null)
    {
 
        // Call recursively the DFS
        // function for left child
        pair ptemp
            = sumofsubtree(root.left);
 
        // Increment the sum of depths
        // by ptemp.first+p.temp.first
        p.second += ptemp.first
                    + ptemp.second;
 
        // Increment p.fisrt by count
        // of noded in left subtree
        p.first += ptemp.first;
    }
 
    // Check if right is not null
    if (root.right != null)
    {
 
        // Call recursively the DFS
        // function for right child
        pair ptemp
            = sumofsubtree(root.right);
 
        // Increment the sum of depths
        // by ptemp.first+p.temp.first
        p.second += ptemp.first
                    + ptemp.second;
 
        // Increment p.fisrt by count of
        // nodes in right subtree
        p.first += ptemp.first;
    }
 
    // Increment the result by total
    // sum of depth in current subtree
    ans += p.second;
 
    // Return p
    return p;
}
 
// Driver Code
public static void main(String[] args)
{
    // Given Tree
    TreeNode root = newNode(1);
    root.left = newNode(2);
    root.right = newNode(3);
    root.left.left = newNode(4);
    root.left.right = newNode(5);
    root.right.left = newNode(6);
    root.right.right = newNode(7);
    root.left.left.left = newNode(8);
    root.left.left.right = newNode(9);
    ans = 0;
    sumofsubtree(root);
 
    // Print the result
    System.out.print(ans);
}
}
 
// This code is contributed by shikhasingrajput


C#
// C# program for the above approach
using System;
 
public class GFG
{
    static int ans;
    class pair
    {
        public int first, second;
        public pair(int first, int second) 
        {
            this.first = first;
            this.second = second;
        }   
    }
   
// Binary tree node
class TreeNode
{
    public int data;
    public TreeNode left;
    public TreeNode right;
};
 
// Function to allocate a new
// node with the given data and
// null in its left and right pointers
static TreeNode newNode(int data)
{
    TreeNode Node = new TreeNode();
    Node.data = data;
    Node.left = null;
    Node.right = null;
    return (Node);
}
 
// DFS function to calculate the sum
// of depths of all subtrees depth sum
static pair sumofsubtree(TreeNode root)
{
   
    // Store total number of node in
    // its subtree and total sum of
    // depth in its subtree
    pair p = new pair(1, 0);
 
    // Check if left is not null
    if (root.left != null)
    {
 
        // Call recursively the DFS
        // function for left child
        pair ptemp
            = sumofsubtree(root.left);
 
        // Increment the sum of depths
        // by ptemp.first+p.temp.first
        p.second += ptemp.first
                    + ptemp.second;
 
        // Increment p.fisrt by count
        // of noded in left subtree
        p.first += ptemp.first;
    }
 
    // Check if right is not null
    if (root.right != null)
    {
 
        // Call recursively the DFS
        // function for right child
        pair ptemp
            = sumofsubtree(root.right);
 
        // Increment the sum of depths
        // by ptemp.first+p.temp.first
        p.second += ptemp.first
                    + ptemp.second;
 
        // Increment p.fisrt by count of
        // nodes in right subtree
        p.first += ptemp.first;
    }
 
    // Increment the result by total
    // sum of depth in current subtree
    ans += p.second;
 
    // Return p
    return p;
}
 
// Driver Code
public static void Main(String[] args)
{
    // Given Tree
    TreeNode root = newNode(1);
    root.left = newNode(2);
    root.right = newNode(3);
    root.left.left = newNode(4);
    root.left.right = newNode(5);
    root.right.left = newNode(6);
    root.right.right = newNode(7);
    root.left.left.left = newNode(8);
    root.left.left.right = newNode(9);
    ans = 0;
    sumofsubtree(root);
 
    // Print the result
    Console.Write(ans);
}
}
 
  
 
// This code contributed by shikhasingrajput


输出:

26

时间复杂度: O(N 2 )
辅助空间: O(N)

高效的方法:可以基于以下观察来优化上述方法:

请按照以下步骤解决问题:

  • 定义一个递归DFS函数,例如sumofsubtree(root)为:
    • 初始化对p ,该对存储当前节点子树中的总节点数和当前子树中所有节点的深度总和
    • 检查左子节点是否不为NULL ,然后递归调用函数sumoftree(root-> left) ,将p.first增加左子树中节点的总数,并将p.second增加深度的总和。左子树中的所有节点。
    • 检查右子节点是否不为NULL ,然后递归调用函数sumoftree(root-> right) ,将p.first乘以右子树中节点的总数,然后将p.second乘以深度的总和。右子树中的所有节点。
    • ans的总数增加p.second并返回对p。
  • 调用DFS函数sumoftree(root)并打印获得的结果ans

下面是上述方法的实现:

C++

// C++ program for the above approach
#include 
using namespace std;
 
// Binary tree node
class TreeNode {
public:
    int data;
    TreeNode* left;
    TreeNode* right;
};
 
// Function to allocate a new
// node with the given data and
// NULL in its left and right pointers
TreeNode* newNode(int data)
{
    TreeNode* Node = new TreeNode();
    Node->data = data;
    Node->left = NULL;
    Node->right = NULL;
 
    return (Node);
}
 
// DFS function to calculate the sum
// of depths of all subtrees depth sum
pair sumofsubtree(TreeNode* root,
                            int& ans)
{
    // Store total number of node in
    // its subtree and total sum of
    // depth in its subtree
    pair p = make_pair(1, 0);
 
    // Check if left is not NULL
    if (root->left) {
 
        // Call recursively the DFS
        // function for left child
        pair ptemp
            = sumofsubtree(root->left, ans);
 
        // Increment the sum of depths
        // by ptemp.first+p.temp.first
        p.second += ptemp.first
                    + ptemp.second;
 
        // Increment p.fisrt by count
        // of noded in left subtree
        p.first += ptemp.first;
    }
 
    // Check if right is not NULL
    if (root->right) {
 
        // Call recursively the DFS
        // function for right child
        pair ptemp
            = sumofsubtree(root->right, ans);
 
        // Increment the sum of depths
        // by ptemp.first+p.temp.first
        p.second += ptemp.first
                    + ptemp.second;
 
        // Increment p.fisrt by count of
        // nodes in right subtree
        p.first += ptemp.first;
    }
 
    // Increment the result by total
    // sum of depth in current subtree
    ans += p.second;
 
    // Return p
    return p;
}
 
// Driver Code
int main()
{
    // Given Tree
    TreeNode* root = newNode(1);
    root->left = newNode(2);
    root->right = newNode(3);
    root->left->left = newNode(4);
    root->left->right = newNode(5);
    root->right->left = newNode(6);
    root->right->right = newNode(7);
    root->left->left->left = newNode(8);
    root->left->left->right = newNode(9);
 
    int ans = 0;
 
    sumofsubtree(root, ans);
 
    // Print the result
    cout << ans;
 
    return 0;
}

Java

// Java program for the above approach
import java.util.*;
class GFG
{
    static int ans;
    static class pair
    {
        int first, second;
        public pair(int first, int second) 
        {
            this.first = first;
            this.second = second;
        }   
    }
   
// Binary tree node
static class TreeNode
{
    int data;
    TreeNode left;
    TreeNode right;
};
 
// Function to allocate a new
// node with the given data and
// null in its left and right pointers
static TreeNode newNode(int data)
{
    TreeNode Node = new TreeNode();
    Node.data = data;
    Node.left = null;
    Node.right = null;
    return (Node);
}
 
// DFS function to calculate the sum
// of depths of all subtrees depth sum
static pair sumofsubtree(TreeNode root)
{
   
    // Store total number of node in
    // its subtree and total sum of
    // depth in its subtree
    pair p = new pair(1, 0);
 
    // Check if left is not null
    if (root.left != null)
    {
 
        // Call recursively the DFS
        // function for left child
        pair ptemp
            = sumofsubtree(root.left);
 
        // Increment the sum of depths
        // by ptemp.first+p.temp.first
        p.second += ptemp.first
                    + ptemp.second;
 
        // Increment p.fisrt by count
        // of noded in left subtree
        p.first += ptemp.first;
    }
 
    // Check if right is not null
    if (root.right != null)
    {
 
        // Call recursively the DFS
        // function for right child
        pair ptemp
            = sumofsubtree(root.right);
 
        // Increment the sum of depths
        // by ptemp.first+p.temp.first
        p.second += ptemp.first
                    + ptemp.second;
 
        // Increment p.fisrt by count of
        // nodes in right subtree
        p.first += ptemp.first;
    }
 
    // Increment the result by total
    // sum of depth in current subtree
    ans += p.second;
 
    // Return p
    return p;
}
 
// Driver Code
public static void main(String[] args)
{
    // Given Tree
    TreeNode root = newNode(1);
    root.left = newNode(2);
    root.right = newNode(3);
    root.left.left = newNode(4);
    root.left.right = newNode(5);
    root.right.left = newNode(6);
    root.right.right = newNode(7);
    root.left.left.left = newNode(8);
    root.left.left.right = newNode(9);
    ans = 0;
    sumofsubtree(root);
 
    // Print the result
    System.out.print(ans);
}
}
 
// This code is contributed by shikhasingrajput

C#

// C# program for the above approach
using System;
 
public class GFG
{
    static int ans;
    class pair
    {
        public int first, second;
        public pair(int first, int second) 
        {
            this.first = first;
            this.second = second;
        }   
    }
   
// Binary tree node
class TreeNode
{
    public int data;
    public TreeNode left;
    public TreeNode right;
};
 
// Function to allocate a new
// node with the given data and
// null in its left and right pointers
static TreeNode newNode(int data)
{
    TreeNode Node = new TreeNode();
    Node.data = data;
    Node.left = null;
    Node.right = null;
    return (Node);
}
 
// DFS function to calculate the sum
// of depths of all subtrees depth sum
static pair sumofsubtree(TreeNode root)
{
   
    // Store total number of node in
    // its subtree and total sum of
    // depth in its subtree
    pair p = new pair(1, 0);
 
    // Check if left is not null
    if (root.left != null)
    {
 
        // Call recursively the DFS
        // function for left child
        pair ptemp
            = sumofsubtree(root.left);
 
        // Increment the sum of depths
        // by ptemp.first+p.temp.first
        p.second += ptemp.first
                    + ptemp.second;
 
        // Increment p.fisrt by count
        // of noded in left subtree
        p.first += ptemp.first;
    }
 
    // Check if right is not null
    if (root.right != null)
    {
 
        // Call recursively the DFS
        // function for right child
        pair ptemp
            = sumofsubtree(root.right);
 
        // Increment the sum of depths
        // by ptemp.first+p.temp.first
        p.second += ptemp.first
                    + ptemp.second;
 
        // Increment p.fisrt by count of
        // nodes in right subtree
        p.first += ptemp.first;
    }
 
    // Increment the result by total
    // sum of depth in current subtree
    ans += p.second;
 
    // Return p
    return p;
}
 
// Driver Code
public static void Main(String[] args)
{
    // Given Tree
    TreeNode root = newNode(1);
    root.left = newNode(2);
    root.right = newNode(3);
    root.left.left = newNode(4);
    root.left.right = newNode(5);
    root.right.left = newNode(6);
    root.right.right = newNode(7);
    root.left.left.left = newNode(8);
    root.left.left.right = newNode(9);
    ans = 0;
    sumofsubtree(root);
 
    // Print the result
    Console.Write(ans);
}
}
 
  
 
// This code contributed by shikhasingrajput
输出:
26

时间复杂度: O(N)
辅助空间: O(N)