Given an N-ary tree, find and return the node with second largest value in the given tree. Return NULL if no node with required value is present.
For example, in the given tree

Second largest node is 20.
A simple solution is to traverse the array twice. In the first traversal find the maximum value node. In the second traversal find the greatest element node less than the element obtained in first traversal. The time complexity of this solution is O(n).
An Efficient Solution can be to find the second largest element in a single traversal.
Below is the complete algorithm for doing this:
1) Initialize two nodes first and second to NULL as,
first = second = NULL
2) Start traversing the tree,
a) If the current node data say root->key is greater
than first->key then update first and second as,
second = first
first = root
b) If the current node data is in between first and
second, then update second to store the value
of current node as
second = root
3) Return the node stored in second.
Implementation:
C++
#include <bits/stdc++.h>
using namespace std;
struct Node {
int key;
vector<Node*> child;
};
Node* newNode( int key)
{
Node* temp = new Node;
temp->key = key;
return temp;
}
void secondLargestUtil(Node* root, Node** first,
Node** second)
{
if (root == NULL)
return ;
if (!(*first))
*first = root;
else if (root->key > (*first)->key) {
*second = *first;
*first = root;
}
else if (!(*second)) {
if (root->key < (*first)->key) {
*second = root;
}
}
else if (root->key < (*first)->key && root->key > (*second)->key)
*second = root;
int numChildren = root->child.size();
for ( int i = 0; i < numChildren; i++)
secondLargestUtil(root->child[i], first, second);
}
Node* secondLargest(Node* root)
{
Node* second = NULL;
Node* first = NULL;
secondLargestUtil(root, &first, &second);
if (second == NULL)
return NULL;
return second;
}
int main()
{
Node* root = newNode(5);
(root->child).push_back(newNode(1));
(root->child).push_back(newNode(2));
(root->child).push_back(newNode(3));
(root->child[0]->child).push_back(newNode(15));
(root->child[1]->child).push_back(newNode(4));
(root->child[1]->child).push_back(newNode(5));
(root->child[2]->child).push_back(newNode(6));
if (secondLargest(root) != NULL)
cout << "Second largest element is : " << secondLargest(root)->key << endl;
else
cout << "Second largest element not found\n" ;
return 0;
}
|
Java
class GFG
{
static class Node
{
int data;
Node children[];
Node( int n, int data)
{
children = new Node[n];
this .data = data;
}
}
public static Node largest;
public static Node secondLargest;
public static void findSecondLargestHelper(Node root)
{
if (root == null ) {
return ;
}
if (root.data > largest.data) {
secondLargest = largest;
largest = root;
} else if (root.data > secondLargest.data && root.data != largest.data)
secondLargest = root;
for (Node child: root.children)
findSecondLargestHelper(child);
}
public static Node findSecondLargest(Node root)
{
largest = new Node( 0 , Integer.MIN_VALUE);
secondLargest = largest;
findSecondLargestHelper(root);
return secondLargest;
}
public static void main(String[] args)
{
int n = 3 ;
Node root = new Node(n, 1 );
root.children[ 0 ] = new Node(n, 2 );
root.children[ 1 ] = new Node(n, 3 );
root.children[ 2 ] = new Node(n, 4 );
root.children[ 0 ].children[ 0 ] = new Node(n, 5 );
root.children[ 0 ].children[ 1 ] = new Node(n, 6 );
root.children[ 0 ].children[ 2 ] = new Node(n, 7 );
findSecondLargest(root);
System.out.print( "Second Largest Node is: " );
System.out.println(secondLargest.data);
}
}
|
Python3
class Node:
def __init__( self , key):
self .key = key
self .child = []
def newNode(key):
temp = Node(key)
return temp
def secondLargestUtil(root, first, second):
if root is None :
return
if first[ 0 ] is None :
first[ 0 ] = root
elif root.key > first[ 0 ].key:
second[ 0 ] = first[ 0 ]
first[ 0 ] = root
elif second[ 0 ] is None :
if root.key < first[ 0 ].key:
second[ 0 ] = root
elif root.key < first[ 0 ].key and root.key > second[ 0 ].key:
second[ 0 ] = root
for i in range ( len (root.child)):
secondLargestUtil(root.child[i], first, second)
def secondLargest(root):
second = [ None ]
first = [ None ]
secondLargestUtil(root, first, second)
if second[ 0 ] is None :
return None
return second[ 0 ]
if __name__ = = '__main__' :
root = newNode( 5 )
root.child.append(newNode( 1 ))
root.child.append(newNode( 2 ))
root.child.append(newNode( 3 ))
root.child[ 0 ].child.append(newNode( 15 ))
root.child[ 1 ].child.append(newNode( 4 ))
root.child[ 1 ].child.append(newNode( 5 ))
root.child[ 2 ].child.append(newNode( 6 ))
result = secondLargest(root)
if result is not None :
print ( "Second largest element is : " , result.key)
else :
print ( "Second largest element not found" )
|
C#
using System;
public class GFG {
public class Node {
public int data;
public Node[] children;
public Node( int n, int data)
{
children = new Node[n];
this .data = data;
}
}
static Node largest;
static Node secondLargest;
static void findSecondLargestHelper(Node root)
{
if (root == null ) {
return ;
}
if (root.data > largest.data) {
secondLargest = largest;
largest = root;
}
else if (root.data > secondLargest.data
&& root.data != largest.data)
secondLargest = root;
foreach (Node child in root.children)
findSecondLargestHelper(child);
}
static Node findSecondLargest(Node root)
{
largest = new Node(0, Int32.MinValue);
secondLargest = largest;
findSecondLargestHelper(root);
return secondLargest;
}
public static void Main( string [] args)
{
int n = 3;
Node root = new Node(n, 1);
root.children[0] = new Node(n, 2);
root.children[1] = new Node(n, 3);
root.children[2] = new Node(n, 4);
root.children[0].children[0] = new Node(n, 5);
root.children[0].children[1] = new Node(n, 6);
root.children[0].children[2] = new Node(n, 7);
findSecondLargest(root);
Console.Write( "Second Largest Node is: " );
Console.WriteLine(secondLargest.data);
}
}
|
Javascript
<script>
class Node {
constructor(key) {
this .key = key;
this .child = [];
}
}
function newNode(key) {
let temp = new Node(key);
return temp;
}
function secondLargestUtil(root, first, second) {
if (!root) {
return ;
}
if (!first[0]) {
first[0] = root;
}
else if (root.key > first[0].key) {
second[0] = first[0];
first[0] = root;
}
else if (!second[0]) {
if (root.key < first[0].key) {
second[0] = root;
}
}
else if (root.key < first[0].key && root.key > second[0].key) {
second[0] = root;
}
for (let i = 0; i < root.child.length; i++) {
secondLargestUtil(root.child[i], first, second);
}
}
function secondLargest(root) {
let second = [ null ];
let first = [ null ];
secondLargestUtil(root, first, second);
if (!second[0]) {
return null ;
}
return second[0];
}
let root = newNode(5);
root.child.push(newNode(1));
root.child.push(newNode(2));
root.child.push(newNode(3));
root.child[0].child.push(newNode(15));
root.child[1].child.push(newNode(4));
root.child[1].child.push(newNode(5));
root.child[2].child.push(newNode(6));
let result = secondLargest(root);
if (result) {
document.write( "Second largest element is : " , result.key);
} else {
document.write( "Second largest element not found" );
}
</script>
|
Output:
Second largest element is : 6
Time Complexity: O(n) where n is the number of nodes in the tree.
Auxiliary Space: O(n)
If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.
Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!