二叉树中的垂直和|第 2 组(空间优化)
给定一棵二叉树,求同一垂直线上的节点的垂直总和。通过不同的垂直线打印所有总和。
例子:
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
我们在Set 1中讨论了基于散列的解决方案。基于散列的解决方案需要维护一个散列表。我们知道散列需要比其中的条目数更多的空间。在这篇文章中,讨论了基于双链表的解决方案。这里讨论的解决方案只需要链表的 n 个节点,其中 n 是二叉树中垂直行的总数。下面是算法。
verticalSumDLL(root)
1) Create a node of doubly linked list node
with value 0. Let the node be llnode.
2) verticalSumDLL(root, llnode)
verticalSumDLL(tnode, llnode)
1) Add current node's data to its vertical line
llnode.data = llnode.data + tnode.data;
2) Recursively process left subtree
// If left child is not empty
if (tnode.left != null)
{
if (llnode.prev == null)
{
llnode.prev = new LLNode(0);
llnode.prev.next = llnode;
}
verticalSumDLLUtil(tnode.left, llnode.prev);
}
3) Recursively process right subtree
if (tnode.right != null)
{
if (llnode.next == null)
{
llnode.next = new LLNode(0);
llnode.next.prev = llnode;
}
verticalSumDLLUtil(tnode.right, llnode.next);
}
C++
/// C++ program of space optimized solution
/// to find vertical sum of binary tree.
#include
using namespace std;
/// Tree node structure
struct TNode{
int key;
struct TNode *left, *right;
};
/// Function to create new tree node
TNode* newTNode(int key)
{
TNode* temp = new TNode;
temp->key = key;
temp->left = temp->right = NULL;
return temp;
}
/// Doubly linked list structure
struct LLNode{
int key;
struct LLNode *prev, *next;
};
/// Function to create new Linked List Node
LLNode* newLLNode(int key)
{
LLNode* temp = new LLNode;
temp->key = key;
temp->prev = temp->next = NULL;
return temp;
}
/// Function that creates Linked list and store
/// vertical sum in it.
void verticalSumDLLUtil(TNode *root, LLNode *sumNode)
{
/// Update sum of current line by adding value
/// of current tree node.
sumNode->key = sumNode->key + root->key;
/// Recursive call to left subtree.
if(root->left)
{
if(sumNode->prev == NULL)
{
sumNode->prev = newLLNode(0);
sumNode->prev->next = sumNode;
}
verticalSumDLLUtil(root->left, sumNode->prev);
}
/// Recursive call to right subtree.
if(root->right)
{
if(sumNode->next == NULL)
{
sumNode->next = newLLNode(0);
sumNode->next->prev = sumNode;
}
verticalSumDLLUtil(root->right, sumNode->next);
}
}
/// Function to print vertical sum of Tree.
/// It uses verticalSumDLLUtil() to calculate sum.
void verticalSumDLL(TNode* root)
{
/// Create Linked list node for
/// line passing through root.
LLNode* sumNode = newLLNode(0);
/// Compute vertical sum of different lines.
verticalSumDLLUtil(root, sumNode);
/// Make doubly linked list pointer point
/// to first node in list.
while(sumNode->prev != NULL){
sumNode = sumNode->prev;
}
/// Print vertical sum of different lines
/// of binary tree.
while(sumNode != NULL){
cout << sumNode->key <<" ";
sumNode = sumNode->next;
}
}
int main()
{
/*
1
/ \
/ \
2 3
/ \ / \
/ \ / \
4 5 6 7
*/
TNode *root = newTNode(1);
root->left = newTNode(2);
root->right = newTNode(3);
root->left->left = newTNode(4);
root->left->right = newTNode(5);
root->right->left = newTNode(6);
root->right->right = newTNode(7);
cout << "Vertical Sums are\n";
verticalSumDLL(root);
return 0;
}
// This code is contributed by Rahul Titare
Java
// Java implementation of space optimized solution
// to find vertical sum.
public class VerticalSumBinaryTree
{
// Prints vertical sum of different vertical
// lines in tree. This method mainly uses
// verticalSumDLLUtil().
static void verticalSumDLL(TNode root)
{
// Create a doubly linked list node to
// store sum of lines going through root.
// Vertical sum is initialized as 0.
LLNode llnode = new LLNode(0);
// Compute vertical sum of different lines
verticalSumDLLUtil(root, llnode);
// llnode refers to sum of vertical line
// going through root. Move llnode to the
// leftmost line.
while (llnode.prev != null)
llnode = llnode.prev;
// Prints vertical sum of all lines starting
// from leftmost vertical line
while (llnode != null)
{
System.out.print(llnode.data +" ");
llnode = llnode.next;
}
}
// Constructs linked list
static void verticalSumDLLUtil(TNode tnode,
LLNode llnode)
{
// Add current node's data to its vertical line
llnode.data = llnode.data + tnode.data;
// Recursively process left subtree
if (tnode.left != null)
{
if (llnode.prev == null)
{
llnode.prev = new LLNode(0);
llnode.prev.next = llnode;
}
verticalSumDLLUtil(tnode.left, llnode.prev);
}
// Process right subtree
if (tnode.right != null)
{
if (llnode.next == null)
{
llnode.next = new LLNode(0);
llnode.next.prev = llnode;
}
verticalSumDLLUtil(tnode.right, llnode.next);
}
}
// Driver code
public static void main(String[] args)
{
// Let us construct the tree shown above
TNode root = new TNode(1);
root.left = new TNode(2);
root.right = new TNode(3);
root.left.left = new TNode(4);
root.left.right = new TNode(5);
root.right.left = new TNode(6);
root.right.right = new TNode(7);
System.out.println("Vertical Sums are");
verticalSumDLL(root);
}
// Doubly Linked List Node
static class LLNode
{
int data;
LLNode prev, next;
public LLNode(int d) { data = d; }
}
// Binary Tree Node
static class TNode
{
int data;
TNode left, right;
public TNode(int d) { data = d; }
}
}
Python3
# Python3 program of space optimized
# solution to find vertical sum of
# binary tree.
# Tree node structure
class TNode:
def __init__(self, key):
self.key = key
self.left = None
self.right = None
# Doubly linked list structure
class LLNode:
def __init__(self, key):
self.key = key
self.prev = None
self.next = None
# Function that creates Linked list and store
# vertical sum in it.
def verticalSumDLLUtil(root: TNode,
sumNode: LLNode) -> None:
# Update sum of current line by adding
# value of current tree node.
sumNode.key = sumNode.key + root.key
# Recursive call to left subtree.
if (root.left):
if (sumNode.prev == None):
sumNode.prev = LLNode(0)
sumNode.prev.next = sumNode
verticalSumDLLUtil(root.left,
sumNode.prev)
# Recursive call to right subtree.
if (root.right):
if (sumNode.next == None):
sumNode.next = LLNode(0)
sumNode.next.prev = sumNode
verticalSumDLLUtil(root.right,
sumNode.next)
# Function to print vertical sum of Tree.
# It uses verticalSumDLLUtil() to calculate sum.
def verticalSumDLL(root: TNode) -> None:
# Create Linked list node for
# line passing through root.
sumNode = LLNode(0)
# Compute vertical sum of different lines.
verticalSumDLLUtil(root, sumNode)
# Make doubly linked list pointer point
# to first node in list.
while (sumNode.prev != None):
sumNode = sumNode.prev
# Print vertical sum of different lines
# of binary tree.
while (sumNode != None):
print(sumNode.key, end = " ")
sumNode = sumNode.next
# Driver code
if __name__ == "__main__":
'''
1
/ \
/ \
2 3
/ \ / \
/ \ / \
4 5 6 7
'''
root = TNode(1)
root.left = TNode(2)
root.right = TNode(3)
root.left.left = TNode(4)
root.left.right = TNode(5)
root.right.left = TNode(6)
root.right.right = TNode(7)
print("Vertical Sums are")
verticalSumDLL(root)
# This code is contributed by sanjeev2552
C#
// C# implementation of space optimized
// solution to find vertical sum.
using System;
class GFG
{
// Prints vertical sum of different vertical
// lines in tree. This method mainly uses
// verticalSumDLLUtil().
public static void verticalSumDLL(TNode root)
{
// Create a doubly linked list node to
// store sum of lines going through root.
// Vertical sum is initialized as 0.
LLNode llnode = new LLNode(0);
// Compute vertical sum of different lines
verticalSumDLLUtil(root, llnode);
// llnode refers to sum of vertical line
// going through root. Move llnode to the
// leftmost line.
while (llnode.prev != null)
{
llnode = llnode.prev;
}
// Prints vertical sum of all lines
// starting from leftmost vertical line
while (llnode != null)
{
Console.Write(llnode.data + " ");
llnode = llnode.next;
}
}
// Constructs linked list
public static void verticalSumDLLUtil(TNode tnode,
LLNode llnode)
{
// Add current node's data to
// its vertical line
llnode.data = llnode.data + tnode.data;
// Recursively process left subtree
if (tnode.left != null)
{
if (llnode.prev == null)
{
llnode.prev = new LLNode(0);
llnode.prev.next = llnode;
}
verticalSumDLLUtil(tnode.left, llnode.prev);
}
// Process right subtree
if (tnode.right != null)
{
if (llnode.next == null)
{
llnode.next = new LLNode(0);
llnode.next.prev = llnode;
}
verticalSumDLLUtil(tnode.right, llnode.next);
}
}
// Doubly Linked List Node
public class LLNode
{
public int data;
public LLNode prev, next;
public LLNode(int d)
{
data = d;
}
}
// Binary Tree Node
public class TNode
{
public int data;
public TNode left, right;
public TNode(int d)
{
data = d;
}
}
// Driver code
public static void Main(string[] args)
{
// Let us construct the tree shown above
TNode root = new TNode(1);
root.left = new TNode(2);
root.right = new TNode(3);
root.left.left = new TNode(4);
root.left.right = new TNode(5);
root.right.left = new TNode(6);
root.right.right = new TNode(7);
Console.WriteLine("Vertical Sums are");
verticalSumDLL(root);
}
}
// This code is contributed by Shrikant13
Javascript
输出 :
Vertical Sums are
4 2 12 3 7