📌  相关文章
📜  给定二叉树的垂直总和 |设置 1

📅  最后修改于: 2021-10-27 08:20:31             🧑  作者: Mango

给定一棵二叉树,求在同一垂直线上的节点的垂直和。通过不同的垂直线打印所有总和。

例子:

1
    /   \
  2      3
 / \    / \
4   5  6   7

树有5条垂直线

Vertical-Line-1 只有一个节点 4 => 垂直总和为 4
Vertical-Line-2:只有一个节点 2=> 垂直和为 2
Vertical-Line-3:有三个节点:1,5,6 => 垂直和为 1+5+6 = 12
Vertical-Line-4:只有一个节点 3 => 垂直总和为 3
Vertical-Line-5:只有一个节点 7 => 垂直总和为 7

所以预期输出是 4、2、12、3 和 7

我们需要检查所有节点与根的水平距离。如果两个节点具有相同的水平距离 (HD),则它们在同一条垂直线上。高清的想法很简单。根的HD为0,右边缘(连接到右子树的边缘)被认为是+1水平距离,左边缘被认为是-1水平距离。例如,在上面的树中,节点 4 的 HD 为 -2,节点 2 的 HD 为 -1,5 和 6 的 HD 为 0,节点 7 的 HD 为 +2。
我们可以对给定的二叉树进行有序遍历。在遍历树时,我们可以递归计算 HD。我们最初将根的水平距离设为 0。对于左子树,我们将水平距离作为根的水平距离减 1 传递。对于右子树,我们将水平距离作为根的水平距离加 1 传递。

以下是相同的Java实现。 HashMap 用于存储不同水平距离的垂直总和。感谢 Nages 提出这种方法。

C++
// C++ program to find Vertical Sum in
// a given Binary Tree
#include
using namespace std;
  
struct Node
{
    int data;
    struct Node *left, *right;
};
  
// A utility function to create a new
// Binary Tree node
Node* newNode(int data)
{
    Node *temp = new Node;
    temp->data = data;
    temp->left = temp->right = NULL;
    return temp;
}
  
// Traverses the tree in in-order form and
// populates a hashMap that contains the
// vertical sum
void verticalSumUtil(Node *node, int hd,
                     map &Map)
{
    // Base case
    if (node == NULL) return;
  
    // Recur for left subtree
    verticalSumUtil(node->left, hd-1, Map);
  
    // Add val of current node to
    // map entry of corresponding hd
    Map[hd] += node->data;
  
    // Recur for right subtree
    verticalSumUtil(node->right, hd+1, Map);
}
  
// Function to find vertical sum
void verticalSum(Node *root)
{
    // a map to store sum of nodes for each 
    // horizontal distance
    map < int, int> Map;
    map < int, int> :: iterator it;
  
    // populate the map
    verticalSumUtil(root, 0, Map);
  
    // Prints the values stored by VerticalSumUtil()
    for (it = Map.begin(); it != Map.end(); ++it)
    {
        cout << it->first << ": "
             << it->second << endl;
    }
}
  
// Driver program to test above functions
int main()
{
    // Create binary tree as shown in above figure
    Node *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->right->left->right = newNode(8);
    root->right->right->right = newNode(9);
  
    cout << "Following are the values of vertical"
            " sums with the positions of the "
            "columns with respect to root\n";
    verticalSum(root);
  
    return 0;
}
// This code is contributed by Aditi Sharma


Java
import java.util.TreeMap;
   
// Class for a tree node
class TreeNode {
   
    // data members
    private int key;
    private TreeNode left;
    private TreeNode right;
   
    // Accessor methods
    public int key()        { return key; }
    public TreeNode left()  { return left; }
    public TreeNode right() { return right; }
   
    // Constructor
    public TreeNode(int key)
   { this.key = key; left = null; right = null; }
   
    // Methods to set left and right subtrees
    public void setLeft(TreeNode left)   { this.left = left; }
    public void setRight(TreeNode right) { this.right = right; }
}
   
// Class for a Binary Tree
class Tree {
   
    private TreeNode root;
   
    // Constructors
    public Tree() { root = null; }
    public Tree(TreeNode n) { root = n; }
   
    // Method to be called by the consumer classes 
    // like Main class
    public void VerticalSumMain() { VerticalSum(root); }
   
    // A wrapper over VerticalSumUtil()
    private void VerticalSum(TreeNode root) {
   
        // base case
        if (root == null) { return; }
   
        // Creates an empty TreeMap hM
        TreeMap hM =
                   new TreeMap();
   
        // Calls the VerticalSumUtil() to store the 
        // vertical sum values in hM
        VerticalSumUtil(root, 0, hM);
   
        // Prints the values stored by VerticalSumUtil()
        if (hM != null) {
            System.out.println(hM.entrySet());
        }
    }
   
    // Traverses the tree in in-order form and builds
    // a hashMap hM that contains the vertical sum
    private void VerticalSumUtil(TreeNode root, int hD,
                         TreeMap hM) {
   
        // base case
        if (root == null) {  return; }
   
        // Store the values in hM for left subtree
        VerticalSumUtil(root.left(), hD - 1, hM);
   
        // Update vertical sum for hD of this node
        int prevSum = (hM.get(hD) == null) ? 0 : hM.get(hD);
        hM.put(hD, prevSum + root.key());
   
        // Store the values in hM for right subtree
        VerticalSumUtil(root.right(), hD + 1, hM);
    }
}
   
// Driver class to test the verticalSum methods
public class Main {
   
    public static void main(String[] args) {
        /* Create the following Binary Tree
              1
            /    \
          2        3
         / \      / \
        4   5    6   7
   
        */
        TreeNode root = new TreeNode(1);
        root.setLeft(new TreeNode(2));
        root.setRight(new TreeNode(3));
        root.left().setLeft(new TreeNode(4));
        root.left().setRight(new TreeNode(5));
        root.right().setLeft(new TreeNode(6));
        root.right().setRight(new TreeNode(7));
        Tree t = new Tree(root);
   
        System.out.println("Following are the values of" + 
                           " vertical sums with the positions" +
                        " of the columns with respect to root ");
        t.VerticalSumMain();
    }
}


Python3
# Python3 program to find Vertical Sum in 
# a given Binary Tree 
  
# Node defintion 
class newNode: 
      
    def __init__(self, data): 
          
        self.left = None
        self.right = None
        self.data = data 
          
# Traverses the tree in in-order form and 
# populates a hashMap that contains the 
# vertical sum 
def verticalSumUtil(root, hd, Map): 
  
    # Base case 
    if(root == None):
        return
      
    # Recur for left subtree 
    verticalSumUtil(root.left, hd - 1, Map) 
  
    # Add val of current node to 
    # map entry of corresponding hd 
    if(hd in Map.keys()):
        Map[hd] = Map[hd] + root.data
    else:
        Map[hd] = root.data
          
    # Recur for right subtree 
    verticalSumUtil(root.right, hd + 1, Map)
      
# Function to find vertical_sum 
def verticalSum(root): 
  
    # a dictionary to store sum of
    # nodes for each horizontal distance 
    Map = {}
      
    # Populate the dictionary
    verticalSumUtil(root, 0, Map); 
  
    # Prints the values stored
    # by VerticalSumUtil() 
    for i,j in Map.items():
        print(i, "=", j, end = ", ")
      
# Driver Code 
if __name__ == "__main__": 
      
    '''      Create the following Binary Tree
              1
            /    \
          2        3
         / \      / \
        4   5    6   7 
    '''
    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)
      
    print("Following are the values of vertical "
          "sums with the positions of the "
          "columns with respect to root")
      
    verticalSum(root)
      
# This code is contributed by vipinyadav15799


C#
// C# program to find Vertical Sum in
// a given Binary Tree
using System;
using System.Collections.Generic;
  
// Class for a tree node
class TreeNode 
{
  
    // data members
    public int key;
    public TreeNode left;
    public TreeNode right;
  
    // Accessor methods
    public int Key()
    { 
        return key; 
    }
    public TreeNode Left() { return left; }
    public TreeNode Right() { return right; }
  
    // Constructor
    public TreeNode(int key)
    { 
        this.key = key; 
        left = null;
        right = null; 
    }
  
    // Methods to set left and right subtrees
    public void setLeft(TreeNode left) 
    { 
        this.left = left; 
    }
    public void setRight(TreeNode right) 
    { 
        this.right = right; 
    }
}
  
// Class for a Binary Tree
class Tree 
{
    private TreeNode root;
  
    // Constructors
    public Tree() { root = null; }
    public Tree(TreeNode n) { root = n; }
  
    // Method to be called by the consumer classes 
    // like Main class
    public void VerticalSumMain() 
    { 
        VerticalSum(root); 
    }
  
    // A wrapper over VerticalSumUtil()
    private void VerticalSum(TreeNode root)
    {
  
        // base case
        if (root == null) { return; }
  
        // Creates an empty hashMap hM
        Dictionary hM = new Dictionary();
  
        // Calls the VerticalSumUtil() to store the 
        // vertical sum values in hM
        VerticalSumUtil(root, 0, hM);
  
        // Prints the values stored by VerticalSumUtil()
        if (hM != null) 
        {
            Console.Write("[");
            foreach(KeyValuePair entry in hM)
            {
                Console.Write(entry.Key + " = " + 
                              entry.Value + ", ");
            }
            Console.Write("]");
        }
    }
  
    // Traverses the tree in in-order form and builds
    // a hashMap hM that contains the vertical sum
    private void VerticalSumUtil(TreeNode root, int hD,
                                 Dictionary hM)
    {
  
        // base case
        if (root == null) { return; }
  
        // Store the values in hM for left subtree
        VerticalSumUtil(root.Left(), hD - 1, hM);
  
        // Update vertical sum for hD of this node
        int prevSum = 0;
        if(hM.ContainsKey(hD))
        {
            prevSum = hM[hD];
            hM[hD] = prevSum + root.Key();
        }
        else
            hM.Add(hD, prevSum + root.Key());
  
        // Store the values in hM for right subtree
        VerticalSumUtil(root.Right(), hD + 1, hM);
    }
}
  
// Driver Code
public class GFG
{
    public static void Main(String[] args) 
    {
        /* Create the following Binary Tree
            1
            / \
        2     3
        / \     / \
        4 5 6 7
  
        */
        TreeNode root = new TreeNode(1);
        root.setLeft(new TreeNode(2));
        root.setRight(new TreeNode(3));
        root.Left().setLeft(new TreeNode(4));
        root.Left().setRight(new TreeNode(5));
        root.Right().setLeft(new TreeNode(6));
        root.Right().setRight(new TreeNode(7));
        Tree t = new Tree(root);
  
        Console.WriteLine("Following are the values of" + 
                          " vertical sums with the positions" +
                          " of the columns with respect to root ");
        t.VerticalSumMain();
    }
}
  
// This code is contributed by Rajput-Ji


二叉树的垂直和|设置 2(空间优化)

时间复杂度:O(n)

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程