考虑在节点之间通过的坡度-1线(下图中的虚线)。二叉树中的对角线总和是位于这些行之间的所有节点数据的总和。给定二叉树,打印所有对角线总和。
对于以下输入树,输出应为9、19、42。
9是1、3和5的总和。
19是2、6、4和7的总和。
42是9、10、11和12的总和。
方法1
算法:
这个想法是要跟踪从顶部对角线穿过根的垂直距离。我们增加垂直距离,直到下一个对角线。
- 将垂直距离为0的根添加到队列中。
- 处理所有合适的孩子和合适的孩子的权利之和,依此类推。
- 将左子节点当前节点添加到队列中,以供以后处理。左子节点的垂直距离是当前节点的垂直距离加1。
- 继续执行第二,第三和第四步,直到队列为空。
以下是上述想法的实现。
C++
// C++ Program to find diagonal
// sum in a Binary Tree
#include
using namespace std;
struct Node
{
int data;
struct Node* left;
struct Node* right;
};
struct Node* newNode(int data)
{
struct Node* Node =
(struct Node*)malloc(sizeof(struct Node));
Node->data = data;
Node->left = Node->right = NULL;
return Node;
}
// root - root of the binary tree
// vd - vertical distance diagonally
// diagonalSum - map to store Diagonal
// Sum(Passed by Reference)
void diagonalSumUtil(struct Node* root,
int vd, map &diagonalSum)
{
if(!root)
return;
diagonalSum[vd] += root->data;
// increase the vertical distance if left child
diagonalSumUtil(root->left, vd + 1, diagonalSum);
// vertical distance remains same for right child
diagonalSumUtil(root->right, vd, diagonalSum);
}
// Function to calculate diagonal
// sum of given binary tree
void diagonalSum(struct Node* root)
{
// create a map to store Diagonal Sum
map diagonalSum;
diagonalSumUtil(root, 0, diagonalSum);
map::iterator it;
cout << "Diagonal sum in a binary tree is - ";
for(it = diagonalSum.begin();
it != diagonalSum.end(); ++it)
{
cout << it->second << " ";
}
}
// Driver code
int main()
{
struct Node* root = newNode(1);
root->left = newNode(2);
root->right = newNode(3);
root->left->left = newNode(9);
root->left->right = newNode(6);
root->right->left = newNode(4);
root->right->right = newNode(5);
root->right->left->right = newNode(7);
root->right->left->left = newNode(12);
root->left->right->left = newNode(11);
root->left->left->right = newNode(10);
diagonalSum(root);
return 0;
}
// This code is contributed by Aditya Goel
Java
// Java Program to find diagonal sum in a Binary Tree
import java.util.*;
import java.util.Map.Entry;
//Tree node
class TreeNode
{
int data; //node data
int vd; //vertical distance diagonally
TreeNode left, right; //left and right child's reference
// Tree node constructor
public TreeNode(int data)
{
this.data = data;
vd = Integer.MAX_VALUE;
left = right = null;
}
}
// Tree class
class Tree
{
TreeNode root;//Tree root
// Tree constructor
public Tree(TreeNode root) { this.root = root; }
// Diagonal sum method
public void diagonalSum()
{
// Queue which stores tree nodes
Queue queue = new LinkedList();
// Map to store sum of node's data lying diagonally
Map map = new TreeMap<>();
// Assign the root's vertical distance as 0.
root.vd = 0;
// Add root node to the queue
queue.add(root);
// Loop while the queue is not empty
while (!queue.isEmpty())
{
// Remove the front tree node from queue.
TreeNode curr = queue.remove();
// Get the vertical distance of the dequeued node.
int vd = curr.vd;
// Sum over this node's right-child, right-of-right-child
// and so on
while (curr != null)
{
int prevSum = (map.get(vd) == null)? 0: map.get(vd);
map.put(vd, prevSum + curr.data);
// If for any node the left child is not null add
// it to the queue for future processing.
if (curr.left != null)
{
curr.left.vd = vd+1;
queue.add(curr.left);
}
// Move to the current node's right child.
curr = curr.right;
}
}
// Make an entry set from map.
Set> set = map.entrySet();
// Make an iterator
Iterator> iterator = set.iterator();
// Traverse the map elements using the iterator.
System.out.print("Diagonal sum in a binary tree is - ");
while (iterator.hasNext())
{
Map.Entry me = iterator.next();
System.out.print(me.getValue()+" ");
}
}
}
//Driver class
public class DiagonalSum
{
public static void main(String[] args)
{
TreeNode root = new TreeNode(1);
root.left = new TreeNode(2);
root.right = new TreeNode(3);
root.left.left = new TreeNode(9);
root.left.right = new TreeNode(6);
root.right.left = new TreeNode(4);
root.right.right = new TreeNode(5);
root.right.left.left = new TreeNode(12);
root.right.left.right = new TreeNode(7);
root.left.right.left = new TreeNode(11);
root.left.left.right = new TreeNode(10);
Tree tree = new Tree(root);
tree.diagonalSum();
}
}
Python3
# Program to find diagonal sum in a Binary Tree
class newNode:
def __init__(self, data):
self.data = data
self.left = self.right = None
# Function to compute height and
# root - root of the binary tree
# vd - vertical distance diagonally
# diagonalSum - map to store Diagonal
# Sum(Passed by Reference)
def diagonalSumUtil(root, vd, diagonalSum) :
if(not root):
return
if vd not in diagonalSum:
diagonalSum[vd] = 0
diagonalSum[vd] += root.data
# increase the vertical distance
# if left child
diagonalSumUtil(root.left, vd + 1,
diagonalSum)
# vertical distance remains same
# for right child
diagonalSumUtil(root.right, vd,
diagonalSum)
# Function to calculate diagonal
# sum of given binary tree
def diagonalSum(root) :
# create a map to store Diagonal Sum
diagonalSum = dict()
diagonalSumUtil(root, 0, diagonalSum)
print("Diagonal sum in a binary tree is - ",
end = "")
for it in diagonalSum:
print(diagonalSum[it], end = " ")
# Driver Code
if __name__ == '__main__':
root = newNode(1)
root.left = newNode(2)
root.right = newNode(3)
root.left.left = newNode(9)
root.left.right = newNode(6)
root.right.left = newNode(4)
root.right.right = newNode(5)
root.right.left.right = newNode(7)
root.right.left.left = newNode(12)
root.left.right.left = newNode(11)
root.left.left.right = newNode(10)
diagonalSum(root)
# This code is contributed
# by SHUBHAMSINGH10
C#
// C# Program to find diagonal sum in a Binary Tree
using System;
using System.Collections.Generic;
// Tree node
public
class TreeNode
{
public
int data; // node data
public
int vd; // vertical distance diagonally
public
TreeNode left, right; // left and right child's reference
// Tree node constructor
public TreeNode(int data)
{
this.data = data;
vd = int.MaxValue;
left = right = null;
}
}
// Tree class
public class Tree
{
TreeNode root;//T ree root
// Tree constructor
public Tree(TreeNode root)
{
this.root = root;
}
// Diagonal sum method
public void diagonalSum()
{
// Queue which stores tree nodes
Queue queue = new Queue();
// Map to store sum of node's data lying diagonally
Dictionary map = new Dictionary();
// Assign the root's vertical distance as 0.
root.vd = 0;
// Add root node to the queue
queue.Enqueue(root);
// Loop while the queue is not empty
while (queue.Count != 0)
{
// Remove the front tree node from queue.
TreeNode curr = queue.Dequeue();
// Get the vertical distance of the dequeued node.
int vd = curr.vd;
// Sum over this node's right-child, right-of-right-child
// and so on
while (curr != null)
{
int prevSum;
if(!map.ContainsKey(vd))
prevSum = 0;
else
prevSum = map[vd];
if(map.ContainsKey(vd))
map[vd] = prevSum + curr.data;
else
map.Add(vd, prevSum + curr.data);
// If for any node the left child is not null add
// it to the queue for future processing.
if (curr.left != null)
{
curr.left.vd = vd + 1;
queue.Enqueue(curr.left);
}
// Move to the current node's right child.
curr = curr.right;
}
}
// Traverse the map elements using the iterator.
Console.Write("Diagonal sum in a binary tree is - ");
foreach(KeyValuePair iterator in map)
{
// Map.Entry me = iterator.next();
Console.Write(iterator.Value + " ");
}
}
}
// Driver class
public class DiagonalSum
{
public static void Main(String[] args)
{
TreeNode root = new TreeNode(1);
root.left = new TreeNode(2);
root.right = new TreeNode(3);
root.left.left = new TreeNode(9);
root.left.right = new TreeNode(6);
root.right.left = new TreeNode(4);
root.right.right = new TreeNode(5);
root.right.left.left = new TreeNode(12);
root.right.left.right = new TreeNode(7);
root.left.right.left = new TreeNode(11);
root.left.left.right = new TreeNode(10);
Tree tree = new Tree(root);
tree.diagonalSum();
}
}
// This code is contributed by gauravrajput1
C++
// C++ Program to calculate the
// sum of diagonal nodes.
#include
using namespace std;
// Node Structure
struct Node {
int data;
Node *left, *right;
};
// to map the node with level - index
map grid;
// Function to create new node
struct Node* newNode(int data)
{
struct Node* Node
= (struct Node*)malloc(sizeof(struct Node));
Node->data = data;
Node->left = Node->right = NULL;
return Node;
}
// recursvise function to calculate sum of elements
// where level - index is same.
void addConsideringGrid(Node* root, int level, int index)
{
// if there is no child then return
if (root == NULL)
return;
// add the element in the group of node
// whose level - index is equal
grid[level - index] += (root->data);
// left child call
addConsideringGrid(root->left, level + 1, index - 1);
// right child call
addConsideringGrid(root->right, level + 1, index + 1);
}
vector diagonalSum(Node* root)
{
grid.clear();
// Function call
addConsideringGrid(root, 0, 0);
vector ans;
// for different values of level - index
// add te sum of those node to answer
for (auto x : grid) {
ans.push_back(x.second);
}
return ans;
}
// Driver code
int main()
{
// build binary tree
struct Node* root = newNode(1);
root->left = newNode(2);
root->right = newNode(3);
root->left->left = newNode(9);
root->left->right = newNode(6);
root->right->left = newNode(4);
root->right->right = newNode(5);
root->right->left->right = newNode(7);
root->right->left->left = newNode(12);
root->left->right->left = newNode(11);
root->left->left->right = newNode(10);
// Function Call
vector v = diagonalSum(root);
// print the daigonal sums
for (int i = 0; i < v.size(); i++)
cout << v[i] << " ";
return 0;
}
Java
// Java Program to calculate the
// sum of diagonal nodes.
import java.util.*;
class GFG
{
// Node Structure
static class Node
{
int data;
Node left, right;
};
// to map the node with level - index
static HashMap grid = new HashMap<>();
// Function to create new node
static Node newNode(int data)
{
Node Node = new Node();
Node.data = data;
Node.left = Node.right = null;
return Node;
}
// recursvise function to calculate sum of elements
// where level - index is same.
static void addConsideringGrid(Node root, int level, int index)
{
// if there is no child then return
if (root == null)
return;
// add the element in the group of node
// whose level - index is equal
if(grid.containsKey(level-index))
grid.put(level - index,grid.get(level-index) + (root.data));
else
grid.put(level-index, root.data);
// left child call
addConsideringGrid(root.left, level + 1, index - 1);
// right child call
addConsideringGrid(root.right, level + 1, index + 1);
}
static Vector diagonalSum(Node root)
{
grid.clear();
// Function call
addConsideringGrid(root, 0, 0);
Vector ans = new Vector<>();
// for different values of level - index
// add te sum of those node to answer
for (Map.Entry x : grid.entrySet())
{
ans.add(x.getValue());
}
return ans;
}
// Driver code
public static void main(String[] args)
{
// build binary tree
Node root = newNode(1);
root.left = newNode(2);
root.right = newNode(3);
root.left.left = newNode(9);
root.left.right = newNode(6);
root.right.left = newNode(4);
root.right.right = newNode(5);
root.right.left.right = newNode(7);
root.right.left.left = newNode(12);
root.left.right.left = newNode(11);
root.left.left.right = newNode(10);
// Function Call
Vector v = diagonalSum(root);
// print the daigonal sums
for (int i = 0; i < v.size(); i++)
System.out.print(v.get(i) + " ");
}
}
// This code is contributed by Rajput-Ji .
Python3
# Python3 program calculate the
# sum of diagonal nodes.
from collections import deque
# A binary tree node structure
class Node:
def __init__(self, key):
self.data = key
self.left = None
self.right = None
# To map the node with level - index
grid = {}
# Recursvise function to calculate
# sum of elements where level - index
# is same
def addConsideringGrid(root, level, index):
global grid
# If there is no child then return
if (root == None):
return
# Add the element in the group of node
# whose level - index is equal
grid[level - index] = (grid.get(level - index, 0) +
root.data)
# Left child call
addConsideringGrid(root.left, level + 1,
index - 1)
# Right child call
addConsideringGrid(root.right, level + 1,
index + 1)
def diagonalSum(root):
# grid.clear()
# Function call
addConsideringGrid(root, 0, 0)
ans = []
# For different values of level - index
# add te sum of those node to answer
for x in grid:
ans.append(grid[x])
return ans
# Driver code
if __name__ == '__main__':
# Build binary tree
root = Node(1)
root.left = Node(2)
root.right = Node(3)
root.left.left = Node(9)
root.left.right = Node(6)
root.right.left = Node(4)
root.right.right = Node(5)
root.right.left.right = Node(7)
root.right.left.left = Node(12)
root.left.right.left = Node(11)
root.left.left.right = Node(10)
# Function Call
v = diagonalSum(root)
# Print the daigonal sums
for i in v:
print(i, end = " ")
# This code is contributed by mohit kumar 29
C#
// C# Program to calculate the
// sum of diagonal nodes.
using System;
using System.Collections.Generic;
public class GFG
{
// Node Structure
public
class Node
{
public
int data;
public
Node left, right;
};
// to map the node with level - index
static Dictionary grid = new Dictionary();
// Function to create new node
static Node newNode(int data)
{
Node Node = new Node();
Node.data = data;
Node.left = Node.right = null;
return Node;
}
// recursvise function to calculate sum of elements
// where level - index is same.
static void addConsideringGrid(Node root, int level, int index)
{
// if there is no child then return
if (root == null)
return;
// add the element in the group of node
// whose level - index is equal
if(grid.ContainsKey(level - index))
grid[level - index] = grid[level - index] + (root.data);
else
grid.Add(level-index, root.data);
// left child call
addConsideringGrid(root.left, level + 1, index - 1);
// right child call
addConsideringGrid(root.right, level + 1, index + 1);
}
static List diagonalSum(Node root)
{
grid.Clear();
// Function call
addConsideringGrid(root, 0, 0);
List ans = new List();
// for different values of level - index
// add te sum of those node to answer
foreach (KeyValuePair x in grid)
{
ans.Add(x.Value);
}
return ans;
}
// Driver code
public static void Main(String[] args)
{
// build binary tree
Node root = newNode(1);
root.left = newNode(2);
root.right = newNode(3);
root.left.left = newNode(9);
root.left.right = newNode(6);
root.right.left = newNode(4);
root.right.right = newNode(5);
root.right.left.right = newNode(7);
root.right.left.left = newNode(12);
root.left.right.left = newNode(11);
root.left.left.right = newNode(10);
// Function Call
List v = diagonalSum(root);
// print the daigonal sums
for (int i = 0; i < v.Count; i++)
Console.Write(v[i] + " ");
}
}
// This code is contributed by Rajput-Ji
输出
Diagonal sum in a binary tree is - 9 19 42
方法2:
该方法背后的思想受到矩阵中对角关系的启发。我们可以观察到,矩阵中位于同一对角线上的所有元素的行和列差异都相同。例如,考虑方阵中的主对角线,我们可以观察到对角线上每个元素的行和列索引的差是相同的,即主对角线上的每个元素的行和列0的差,例如: 0-0、1-1、2-2 ……nn。
同样,每个对角线在行和列上都有其独特的区别,借助于此,我们可以识别每个元素,即对角线所属的元素。
同样的想法可以解决这个问题-
- 我们将把树节点的级别作为它们的行索引,将树节点的宽度作为它们的列索引。
- 我们将每个节点的像元表示为(水平,宽度)
示例-(采用与上述相同的树)
Nodes | Level Index | Width Index |
1 |
0 | 0 |
2 |
1 | -1 |
3 |
1 | 1 |
4 |
2 | 0 |
5 |
2 | 2 |
6 |
2 | 0 |
7 |
3 | 1 |
9 |
2 | -2 |
10 |
3 | -1 |
11 |
3 | -1 |
12 |
3 | -1 |
为了使您形象化,让我们绘制一个矩阵,第一行和第一列分别是宽度和级别索引,
-2 |
-1 |
0 | 1 | 2 | |
0 | 1 | ||||
1 |
2 |
3 | |||
2 | 9 | 6+4 | 5 | ||
3 | 10+11+12 | 7 |
下面是上述想法的实现:
C++
// C++ Program to calculate the
// sum of diagonal nodes.
#include
using namespace std;
// Node Structure
struct Node {
int data;
Node *left, *right;
};
// to map the node with level - index
map grid;
// Function to create new node
struct Node* newNode(int data)
{
struct Node* Node
= (struct Node*)malloc(sizeof(struct Node));
Node->data = data;
Node->left = Node->right = NULL;
return Node;
}
// recursvise function to calculate sum of elements
// where level - index is same.
void addConsideringGrid(Node* root, int level, int index)
{
// if there is no child then return
if (root == NULL)
return;
// add the element in the group of node
// whose level - index is equal
grid[level - index] += (root->data);
// left child call
addConsideringGrid(root->left, level + 1, index - 1);
// right child call
addConsideringGrid(root->right, level + 1, index + 1);
}
vector diagonalSum(Node* root)
{
grid.clear();
// Function call
addConsideringGrid(root, 0, 0);
vector ans;
// for different values of level - index
// add te sum of those node to answer
for (auto x : grid) {
ans.push_back(x.second);
}
return ans;
}
// Driver code
int main()
{
// build binary tree
struct Node* root = newNode(1);
root->left = newNode(2);
root->right = newNode(3);
root->left->left = newNode(9);
root->left->right = newNode(6);
root->right->left = newNode(4);
root->right->right = newNode(5);
root->right->left->right = newNode(7);
root->right->left->left = newNode(12);
root->left->right->left = newNode(11);
root->left->left->right = newNode(10);
// Function Call
vector v = diagonalSum(root);
// print the daigonal sums
for (int i = 0; i < v.size(); i++)
cout << v[i] << " ";
return 0;
}
Java
// Java Program to calculate the
// sum of diagonal nodes.
import java.util.*;
class GFG
{
// Node Structure
static class Node
{
int data;
Node left, right;
};
// to map the node with level - index
static HashMap grid = new HashMap<>();
// Function to create new node
static Node newNode(int data)
{
Node Node = new Node();
Node.data = data;
Node.left = Node.right = null;
return Node;
}
// recursvise function to calculate sum of elements
// where level - index is same.
static void addConsideringGrid(Node root, int level, int index)
{
// if there is no child then return
if (root == null)
return;
// add the element in the group of node
// whose level - index is equal
if(grid.containsKey(level-index))
grid.put(level - index,grid.get(level-index) + (root.data));
else
grid.put(level-index, root.data);
// left child call
addConsideringGrid(root.left, level + 1, index - 1);
// right child call
addConsideringGrid(root.right, level + 1, index + 1);
}
static Vector diagonalSum(Node root)
{
grid.clear();
// Function call
addConsideringGrid(root, 0, 0);
Vector ans = new Vector<>();
// for different values of level - index
// add te sum of those node to answer
for (Map.Entry x : grid.entrySet())
{
ans.add(x.getValue());
}
return ans;
}
// Driver code
public static void main(String[] args)
{
// build binary tree
Node root = newNode(1);
root.left = newNode(2);
root.right = newNode(3);
root.left.left = newNode(9);
root.left.right = newNode(6);
root.right.left = newNode(4);
root.right.right = newNode(5);
root.right.left.right = newNode(7);
root.right.left.left = newNode(12);
root.left.right.left = newNode(11);
root.left.left.right = newNode(10);
// Function Call
Vector v = diagonalSum(root);
// print the daigonal sums
for (int i = 0; i < v.size(); i++)
System.out.print(v.get(i) + " ");
}
}
// This code is contributed by Rajput-Ji .
Python3
# Python3 program calculate the
# sum of diagonal nodes.
from collections import deque
# A binary tree node structure
class Node:
def __init__(self, key):
self.data = key
self.left = None
self.right = None
# To map the node with level - index
grid = {}
# Recursvise function to calculate
# sum of elements where level - index
# is same
def addConsideringGrid(root, level, index):
global grid
# If there is no child then return
if (root == None):
return
# Add the element in the group of node
# whose level - index is equal
grid[level - index] = (grid.get(level - index, 0) +
root.data)
# Left child call
addConsideringGrid(root.left, level + 1,
index - 1)
# Right child call
addConsideringGrid(root.right, level + 1,
index + 1)
def diagonalSum(root):
# grid.clear()
# Function call
addConsideringGrid(root, 0, 0)
ans = []
# For different values of level - index
# add te sum of those node to answer
for x in grid:
ans.append(grid[x])
return ans
# Driver code
if __name__ == '__main__':
# Build binary tree
root = Node(1)
root.left = Node(2)
root.right = Node(3)
root.left.left = Node(9)
root.left.right = Node(6)
root.right.left = Node(4)
root.right.right = Node(5)
root.right.left.right = Node(7)
root.right.left.left = Node(12)
root.left.right.left = Node(11)
root.left.left.right = Node(10)
# Function Call
v = diagonalSum(root)
# Print the daigonal sums
for i in v:
print(i, end = " ")
# This code is contributed by mohit kumar 29
C#
// C# Program to calculate the
// sum of diagonal nodes.
using System;
using System.Collections.Generic;
public class GFG
{
// Node Structure
public
class Node
{
public
int data;
public
Node left, right;
};
// to map the node with level - index
static Dictionary grid = new Dictionary();
// Function to create new node
static Node newNode(int data)
{
Node Node = new Node();
Node.data = data;
Node.left = Node.right = null;
return Node;
}
// recursvise function to calculate sum of elements
// where level - index is same.
static void addConsideringGrid(Node root, int level, int index)
{
// if there is no child then return
if (root == null)
return;
// add the element in the group of node
// whose level - index is equal
if(grid.ContainsKey(level - index))
grid[level - index] = grid[level - index] + (root.data);
else
grid.Add(level-index, root.data);
// left child call
addConsideringGrid(root.left, level + 1, index - 1);
// right child call
addConsideringGrid(root.right, level + 1, index + 1);
}
static List diagonalSum(Node root)
{
grid.Clear();
// Function call
addConsideringGrid(root, 0, 0);
List ans = new List();
// for different values of level - index
// add te sum of those node to answer
foreach (KeyValuePair x in grid)
{
ans.Add(x.Value);
}
return ans;
}
// Driver code
public static void Main(String[] args)
{
// build binary tree
Node root = newNode(1);
root.left = newNode(2);
root.right = newNode(3);
root.left.left = newNode(9);
root.left.right = newNode(6);
root.right.left = newNode(4);
root.right.right = newNode(5);
root.right.left.right = newNode(7);
root.right.left.left = newNode(12);
root.left.right.left = newNode(11);
root.left.left.right = newNode(10);
// Function Call
List v = diagonalSum(root);
// print the daigonal sums
for (int i = 0; i < v.Count; i++)
Console.Write(v[i] + " ");
}
}
// This code is contributed by Rajput-Ji
输出:
9 19 42
时间复杂度-O(n)