How to create a Binary Tree using a String array? - data-structures

I am given an assignment where I need to do the following:
input your binary tree as an array, using the array representation and node labels A, ..., J, as Strings. Label null stands for a non-existent node, not for a node having a value of null.
Check the validity of your binary tree input: each node, excepting the root, should have a father.
Generate the dynamic memory implementation of the tree, using only the nodes with labels different than null.
So far I have:
public class Project1{
public static void main(String[] args){
String[] input = new String[]{"A","B","C","D","E","F","G","H","I","J"};
}
public class BinaryTree<T> implements java.io.Serializable{
private T data;
private BinaryTree<T> left;
private BinaryTree<T> right;
public BinaryTree(T data){
this.data = data;
left = null;
right = null;
}
public T getData(){
return data;
}
public void attachLeft(BinaryTree<T> tree){
if(tree != null){
left = tree;
}
}
public void attachRight(BinaryTree<T> tree){
if(tree != null){
right = tree;
}
}
public BinaryTree<T> detachLeft(){
BinaryTree<T> t = left;
left = null;
return t;
}
public BinaryTree<T> detachRight(){
BinaryTree<T> t = right;
right = null;
return t;
}
public boolean isEmpty(){
return data == null;
}
public void inOrder(BinaryTree<T> tree){
if (tree != null){
inOrder(tree.left);
System.out.println(tree.getData());
inOrder(tree.right);
}
}
public void preOrder(BinaryTree<T> tree){
if(tree != null){
System.out.println(tree.getData());
preOrder(tree.left);
preOrder(tree.right);
}
}
public void postOrder(BinaryTree<T> tree){
if(tree != null){
postOrder(tree.left);
postOrder(tree.right);
System.out.println(tree.getData());
}
}
}
What I don't understand is how to create a BinaryTree using my data from the string array

Related

Struggling terribly on how to start and complete a file

I am unsure how to complete these 3 methods. 4 Reference classes are also given (at the bottom)
I know I have to first start building the tree from the array "a" but I am not sure how to do that. SOS pls help. :(
The data stored in the binary tree are doubles. The binary tree will store the data only on the
leaves. The internal nodes are used for searching only.
Your tree will work like a normal BST, to find a target element, your program will compare it to the root of the current subtree and if the target is less than the value of the root you will recursively search on the left subtree.Otherwise, you will search on the right subtree.
Your tree will allow duplicate values, by keeping track of the
number of times that a particular value appears (this data is kept only in the leaves).
Your binary tree is always created from scratch given a sorted array of doubles, in such a way
that the root of every subtree (not a leaf) contains the average of the maximum element in the
left subtree and the minimum element in the right subtree.
Example:
Suppose that you are given the following array:
1, 2.3, 5.8, 5.8, 7.2, 7.2, 7.2, 8, 9.1, 9.2, 10, 10.3, 10.3, 11.9, 12.1, 12.3, 12.5, 13
The tree that is generated has a root with a value of 10.15, which is the average of the maximum
value of the left subtree (which is 10) and the minimum value of the right subtree (which is 10.3),
so the root has a value of (10+10.3)/2 = 10.15
The leaves have the actual values and the number of times each value appears.
public static Queue<BTNode<dataNode>> makeQueue(double[] a){
// Each element of the given array a must be inserted into a BTNode,
// this method returns a queue of BTNodes, each node will contain a dataNode
// the dataNode will have the value equal to the element of the array
// count equal to the number of times that the element repeats
// min and max must be equal to value.
// the BTNode created must have its parent, right, and left references set to null
return null;
}
public static Queue<BTNode<dataNode>> join(Queue<BTNode<dataNode>> myQueue){
// For every two elements dequeued from myQueue create a new root element and
// make the two dequeued elements be the left and right child of that root.
// Each new root must contain the min value, obtained from the left subtree,
// the max value, obtained from the right subtree, and the value should be
// equal to the average of the maximum value of the left subtree and the
// minimum value of the right subtree, count should be set equal to 0 (internal node)
// Enqueue each new root node into another queue and return that queue.
// In case that only one element is left in myQueue, just enqueue it
// in the queue that will be returned.
return null;
}
public static int search(BTNode<dataNode> root,double target) {
// given a target value recursively search on the left or the right subtrees
// by comparing the value in root to the target. You know that you got to a
// leaf when the value count of the root is not equal to 0.
return 0;
}
---------------
public class dataNode implements Comparable<dataNode>{
public double value;
public int count;
public double max;
public double min;
public dataNode() {
value=0;
count=0;
}
public int compareTo(dataNode node2) {
return 0;
}
public String toString() {
return "("+value+","+count+")";
}
}
---------
public class BTNode<T extends Comparable<T>> {
private T data;
private BTNode<T> left,right,parent;
public BTNode(T data,BTNode<T> left,BTNode<T> right,BTNode<T> parent) {
this.data=data;
this.left=left;
this.right=right;
this.parent=parent;
}
public BTNode<T> getLeft(){
return this.left;
}
public BTNode<T> getRight(){
return this.right;
}
public BTNode<T> getParent(){
return this.parent;
}
public T getData(){
return this.data;
}
public void setLeft(BTNode<T> left) {
this.left=left;
}
public void setRight(BTNode<T> right) {
this.right=right;
}
public void setParent(BTNode<T> parent) {
this.parent=parent;
}
public void setData(T data) {
this.data=data;
}
public String toString() {
return this.data.toString();
}
}
----------
public class DLL<T> {
private Node<T> first;
private Node<T> last;
private int count;
private Node<T> current;
public DLL() {
this.first=null;
this.last=null;
count=0;
}
public T getFirst() {
current=first;
if (first!=null)
return first.getData();
return null;
}
public T getNext() {
if (current!=null) {
current=current.getNext();
return current.getData();
}
return null;
}
public T getLast() {
if (last!=null)
return last.getData();
return null;
}
public void addFirst(T data) {
Node<T> n=new Node<T>(data,null,first);
if (this.first!=null) {
this.first.setPrev(n);
}
else {
this.last=n;
}
this.first=n;
count++;
}
public void addLast(T data) {
Node<T> n=new Node<T>(data,last,null);
if (this.last!=null) {
this.last.setNext(n);
}
else {
this.first=n;
}
this.last=n;
count++;
}
public void deleteFirst() {
if (this.first!=null) {
Node<T> newFirst=this.first.getNext();
this.first=newFirst;
if (newFirst!=null) {
newFirst.setPrev(null);
}
else {
this.last=null;
}
count--;
}
}
public void deleteLast() {
if (this.last!=null) {
Node<T> newLast=this.last.getPrev();
this.last=newLast;
if (newLast!=null) {
newLast.setNext(null);
}
else {
this.first=null;
}
count--;
}
}
public void traverse() {
Node<T> current=this.first;
while (current!=null) {
System.out.print(current.getData()+" ");
current=current.getNext();
}
}
public int size() {
return count;
}
public String toString() {
String ret="";
Node<T> current=this.first;
while (current!=null) {
ret=ret+"+"+current.getData();
current=current.getNext();
}
return ret;
}
}
------------
public class Node<T> {
private T data;
private Node<T> prev;
private Node<T> next;
public Node(T data,Node<T> prev,Node<T> next) {
this.data=data;
this.prev=prev;
this.next=next;
}
public T getData() {
return data;
}
public Node<T> getPrev(){
return prev;
}
public Node<T> getNext(){
return next;
}
public void setPrev(Node<T> prev) {
this.prev=prev;
}
public void setNext(Node<T> next) {
this.next=next;
}
}
-----------
public class Queue<T> {
private DLL<T> myList;
public Queue() {
myList=new DLL<T>();
}
public void enqueue(T element) {
myList.addFirst(element);
}
public T dequeue() {
T element=null;
if (myList.size()>0) {
element = myList.getLast();
myList.deleteLast();
}
return element;
}
public int size() {
return myList.size();
}
public boolean isEmpty() {
return myList.size()==0;
}
public void traverse() {
myList.traverse();
}
public static void main(String[] args) {
Queue<String> myQueue=new Queue<String>();
myQueue.enqueue("the");
myQueue.enqueue("quick");
myQueue.enqueue("brown");
myQueue.enqueue("fox");
myQueue.enqueue("jumps");
myQueue.enqueue("over");
myQueue.traverse();
System.out.println("dequeue->"+myQueue.dequeue());
myQueue.traverse();
myQueue.enqueue("the");
myQueue.enqueue("lazy");
myQueue.traverse();
System.out.println("dequeue->"+myQueue.dequeue());
myQueue.traverse();
}
}

Java8 Stream Collectors - Splitting a list based on sum of values

I am trying partition a list into multiple sublists based on a condition that sum of a particular field should be less than 'x'. Below is sameple code:
public class TestGrouping {
public static class Transaction{
String txnId;
String comment;
Amount amount;
public Transaction(String txnId, String comment, Amount amount) {
this.txnId = txnId;
this.comment = comment;
this.amount = amount;
}
}
public static class Amount{
String amountValue;
public Amount(String amountValue) {
this.amountValue = amountValue;
}
}
public static void main(String[] args) {
List<Transaction> transactionList = new ArrayList<>();
Transaction txn1 = new Transaction("T1","comment1",new Amount("81"));
Transaction txn2 = new Transaction("T2","comment2",new Amount("5"));
Transaction txn3 = new Transaction("T3","comment3",new Amount("12"));
Transaction txn4 = new Transaction("T4","comment4",new Amount("28"));
transactionList.add(txn1);
transactionList.add(txn2);
transactionList.add(txn3);
transactionList.add(txn4);
//below is what i thought might work
// transactionList.stream().collect(groupingBy (r->Collectors.summingInt(Integer.valueOf(r.amount.amountValue)),Collectors.mapping(t -> t, toList())));
}
The goal is to split the transactionList into 2 (or more) sublists - where the sum of 'amount' is less than 100. So i could have a sublist have only txn1 - having amount as 81; and the other sublist have txn2, txn3, txn4 (as sum of these is less 100). Other possibility is - have sublist1 having txn1, txn2, txn3; and another sublist with just txn4. Not trying to create the most 'optimal' lists basically, just that sum of amounts should be less than 100.
Any clues?
The Idea is to use a custom collector to generate a list of pair(amountSum, transactions), the list should initialy be sorted. The accumulator method (here Accumulator.accept) do the grouping logic, I didn't implement combine because there is no need for a combiner in non parallel stream.
Bellow the code snippet, hope it helps.
public class TestStream {
public class Transaction {
String txnId;
String comment;
Amount amount;
public Transaction(String txnId, String comment, Amount amount) {
this.txnId = txnId;
this.comment = comment;
this.amount = amount;
}
}
public class Amount {
String amountValue;
public Amount(String amountValue) {
this.amountValue = amountValue;
}
}
#Test
public void test() {
List<Transaction> transactionList = new ArrayList<>();
Transaction txn1 = new Transaction("T1", "comment1", new Amount("81"));
Transaction txn2 = new Transaction("T2", "comment2", new Amount("5"));
Transaction txn3 = new Transaction("T3", "comment3", new Amount("12"));
Transaction txn4 = new Transaction("T4", "comment4", new Amount("28"));
transactionList.add(txn1);
transactionList.add(txn2);
transactionList.add(txn3);
transactionList.add(txn4);
transactionList.stream()
.sorted(Comparator.comparing(tr -> Integer.valueOf(tr.amount.amountValue)))
.collect(ArrayList<Pair<Integer, List<Transaction>>>::new, Accumulator::accept, (x, y) -> {
})
.forEach(t -> {
System.out.println(t.left);
});
}
static class Accumulator {
public static void accept(List<Pair<Integer, List<Transaction>>> lPair, Transaction tr) {
Pair<Integer, List<Transaction>> lastPair = lPair.isEmpty() ? null : lPair.get(lPair.size() - 1);
Integer amount = Integer.valueOf(tr.amount.amountValue);
if (Objects.isNull(lastPair) || lastPair.left + amount > 100) {
lPair.add(
new TestStream().new Pair<Integer, List<Transaction>>(amount,
Arrays.asList(tr)));
} else {
List<Transaction> newList = new ArrayList<>();
newList.addAll(lastPair.getRight());
newList.add(tr);
lastPair.setLeft(lastPair.getLeft() + amount);
lastPair.setRight(newList);
}
}
}
class Pair<T, V> {
private T left;
private V right;
/**
*
*/
public Pair(T left, V right) {
this.left = left;
this.right = right;
}
public V getRight() {
return right;
}
public T getLeft() {
return left;
}
public void setLeft(T left) {
this.left = left;
}
public void setRight(V right) {
this.right = right;
}
}
}

Why generating a Tree according to initial depth is infinite loop (recursion)?

Somebody help me to find the cause of infinite loop (recursion) ?
root = generate_tree(0) // only the root (0 initial_depth)
root = generate_tree(1) // root and two children (1 initial_depth)
0 or 1 initial_depth is working properly but if greater than 1 it will
cause an infinite loop.
Here's my Pseudo Code of creating a Tree according to initial depth
class Node
children = []
generate_subtree()
//let assume it will create two random nodes and pass it to children
children = two random nodes
Node generate_tree(initial_depth)
if initial_depth == 0
return a random Node
else
root = random node
grow_tree(root, initial_depth)
return root;
grow_tree(tree, init_depth)
if initial_depth == 1
tree.generate_subtree()
else if initial_depth > 1
tree.generate_subtree()
for subtree in tree.children
grow_tree(subtree, initial_depth - 1)
Update
I included my actual code
Im working on Unity with C# script
public List<GNode> TERMINALS = new List<GNode>
{
new CanMove_UP(),
new CanMove_DOWN(),
new CanMove_LEFT(),
new CanMove_RIGHT()
};
public List<GNode> NODES = new List<GNode>
{
new ConstantNum(),
new RandomNum()
};
Main Program
let's say i want to create a tree
Tree tree1 = new Tree(0, NODES, TERMINALS); //working properly
Tree tree2 = new Tree(1, NODES, TERMINALS); //working properly
Tree tree3 = new Tree(2, NODES, TERMINALS); //it will cause infinite loop
GNode.cs
using System;
using System.Collections.Generic;
namespace GP
{
public abstract class GNode
{
public const float TERMINAL_RATIO = 0.2f;
public String data { get; private set; }
public bool is_terminal { get; private set; }
public int depth { get; private set; }
public GNode[] children { get; private set; }
public abstract void initialize(int depth = 0);
public abstract void generate_subtree(List<GNode> nodes, List<GNode> terminals);
public GNode() { }
public GNode(String data, bool is_terminal, int depth = 0)
{
this.initialize(data, is_terminal, depth);
}
protected void initialize(String data, bool is_terminal, int depth = 0)
{
this.data = data;
this.is_terminal = is_terminal;
this.depth = depth;
this.children = new GNode[0];
}
protected void generate_subtree(List<GNode> nodes, List<GNode> terminals, int num_of_childrens)
{
List<GNode> classes = new List<GNode>();
for (int i = 0; i < num_of_childrens; i++)
{
if (nodes.Count > 0 && Utility.GetRandomFloat() > GNode.TERMINAL_RATIO)
classes.Add(nodes[Utility.GetRandomNumber(0, nodes.Count)]);
else
classes.Add(terminals[Utility.GetRandomNumber(0, terminals.Count)]);
classes[i].initialize(this.depth + 1);
}
this.children = classes.ToArray();
}
}
#region NODES
public class ConstantNum : GNode
{
public ConstantNum(int depth = 0)
{
this.initialize(depth);
}
public override void initialize(int depth = 0)
{
base.initialize(Utility.GetRandomNumber(0, 9).ToString(), true, depth);
}
public override void generate_subtree(List<GNode> nodes, List<GNode> terminals)
{
base.generate_subtree(nodes, terminals, 2);
}
}
public class RandomNum : GNode
{
public RandomNum(int depth = 0)
{
this.initialize(depth);
}
public override void initialize(int depth = 0)
{
base.initialize("random", true, depth);
}
public override void generate_subtree(List<GNode> nodes, List<GNode> terminals)
{
base.generate_subtree(nodes, terminals, 2);
}
}
#endregion
#region TERMINALS
public class MeasureNode : GNode
{
public String Measure { set; private get; }
public override void initialize(int depth = 0)
{
base.initialize(this.Measure, true, depth);
}
public override void generate_subtree(List<GNode> nodes, List<GNode> terminals)
{
base.generate_subtree(nodes, terminals, 2);
}
}
public class CanMove_UP : MeasureNode
{
public override void initialize(int depth = 0)
{
base.Measure = "CanMove_UP";
base.initialize(depth);
}
}
public class CanMove_DOWN : MeasureNode
{
public override void initialize(int depth = 0)
{
base.Measure = "CanMove_DOWN";
base.initialize(depth);
}
}
public class CanMove_LEFT : MeasureNode
{
public override void initialize(int depth = 0)
{
base.Measure = "CanMove_LEFT";
base.initialize(depth);
}
}
public class CanMove_RIGHT : MeasureNode
{
public override void initialize(int depth = 0)
{
base.Measure = "CanMove_RIGHT";
base.initialize(depth);
}
}
#endregion
}
Tree.cs
using System;
using System.Collections.Generic;
namespace GP
{
public class Tree
{
private int initial_depth;
private List<GNode> nodes;
private List<GNode> terminals;
private GNode root;
public Tree(int initial_depth, List<GNode> nodes, List<GNode> terminals, GNode root = null)
{
this.initial_depth = initial_depth;
this.nodes = nodes;
this.terminals = terminals;
this.root = root;
if (root == null)
this.root = this.generate_tree(initial_depth, nodes, terminals);
}
public GNode generate_tree(int initial_depth, List<GNode> nodes, List<GNode> terminals)
{
if (initial_depth == 0)
return terminals[Utility.GetRandomNumber(0, terminals.Count)]; //construct a random node from terminals
else
{
GNode tree;
if (Utility.GetRandomFloat() <= GNode.TERMINAL_RATIO)
tree = terminals[Utility.GetRandomNumber(0, terminals.Count)];
else
tree = nodes[Utility.GetRandomNumber(0, nodes.Count)];
this.grow_tree(tree, initial_depth, nodes, terminals);
return tree;
}
}
public void grow_tree(GNode tree, int init_depth, List<GNode> nodes, List<GNode> terminals)
{
if (initial_depth == 1)
tree.generate_subtree(new List<GNode>(), terminals); //empty nodes
else if (initial_depth > 1)
{
tree.generate_subtree(nodes, terminals);
foreach (GNode subtree in tree.children)
this.grow_tree(subtree, initial_depth - 1, nodes, terminals);
}
}
}
}
Utility.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public static class Utility
{
private static readonly System.Random getRandom = new System.Random();
public static int GetRandomNumber(int min, int max)
{
lock (getRandom)
{
return getRandom.Next(min, max);
}
}
public static int GetRandomNumber(int max)
{
return GetRandomNumber(0, max);
}
public static float GetRandomFloat(float min = 0.0f, float max = 1.0f)
{
return Random.Range(min, max);
}
}
class Node:
def __init__(self):
self.children = []
def generate_subtree(self):
self.children.append(Node())
self.children.append(Node())
def generate_tree(initial_depth):
if initial_depth == 0:
return Node()
else:
root = Node()
grow_tree(root, initial_depth)
return root
def grow_tree(tree, initial_depth):
if initial_depth == 1:
tree.generate_subtree()
elif initial_depth > 1:
tree.generate_subtree()
for subtree in tree.children:
grow_tree(subtree, initial_depth - 1)
tree = generate_tree(4)
I have translated the exact pseudo-code that you have written and it is working fine.
Can you post your code, or you can just verify from mine what you are missing.

Longest consecutive sequence in Binary tree

I'm trying to implement the logic for "Longest consecutive sequence in Binary tree". The logic I have implemented inside the method { longestConsecutivePath } is not working as expected for the tree structure. It is giving me the lognest path length as 5.
Output:
curLength : 5
BSTNode node = new BSTNode(1);
node.setRight(new BSTNode(2));
node.getRight().setRight(new BSTNode(3));
node.getRight().getRight().setRight(new BSTNode(4));
node.getRight().getRight().getRight().setRight(new BSTNode(5));
node.getRight().setLeft(new BSTNode(7));
node.getRight().getLeft().setLeft(new BSTNode(8));
node.getRight().getLeft().getLeft().setLeft(new BSTNode(9));
node.getRight().getLeft().getLeft().getLeft().setLeft(new BSTNode(10));
node.getRight().getLeft().getLeft().getLeft().getLeft().setLeft(new BSTNode(11));
node.getRight().getLeft().getLeft().getLeft().getLeft().getLeft().setLeft(new BSTNode(12));
Class implementing the Longest Consecutive sequence logic:
public class LongestConsecutivePath {
static BSTNode root = null;
public LongestConsecutivePath() {
root = createBinaryTree();
System.out.println("Before finding the longest consecutive path:");
inorder();
}
public void inorder() {
if (null == root) {
return;
}
inorder(root);
}
private void inorder(BSTNode node) {
if (null != node) {
inorder(node.getLeft());
System.out.print(node.getData() + " ");
inorder(node.getRight());
}
}
public BSTNode createBinaryTree() {
BSTNode node = new BSTNode(1);
node.setRight(new BSTNode(2));
node.getRight().setRight(new BSTNode(3));
node.getRight().getRight().setRight(new BSTNode(4));
node.getRight().getRight().getRight().setRight(new BSTNode(5));
node.getRight().setLeft(new BSTNode(7));
node.getRight().getLeft().setLeft(new BSTNode(8));
node.getRight().getLeft().getLeft().setLeft(new BSTNode(9));
node.getRight().getLeft().getLeft().getLeft().setLeft(new BSTNode(10));
node.getRight().getLeft().getLeft().getLeft().getLeft().setLeft(new BSTNode(11));
node.getRight().getLeft().getLeft().getLeft().getLeft().getLeft().setLeft(new BSTNode(12));
return node;
}
public int longestConsecutivePath() {
if (null == root) {
return 0;
}
return longestConsecutivePath(root, 0, root.getData() + 1);
}
public int longestConsecutivePath(BSTNode node, int curLength,
int targetLength) {
if (null == node) {
return curLength;
}
if (node.getData() == targetLength) {
System.out.println("\nnode data value: "+node.getData());
curLength += 1;
longestPath = curLength;
} else {
curLength = 1;
}
longestLeft = longestConsecutivePath(node.getLeft(), curLength,
node.getData() + 1);
longestRight = longestConsecutivePath(node.getRight(), curLength,
node.getData() + 1);
return Math.max(curLength, Math.max(longestLeft, longestRight));
}
public static void main(String[] args) {
LongestConsecutivePath consecutivePath = new LongestConsecutivePath();
int curLength = consecutivePath.longestConsecutivePath();
System.out.println("\ncurLength : " + curLength);
}
}
BSTNode.java
public class BSTNode {
BSTNode left, right;
int data;
/* Default constructor */
public BSTNode() {
left = null;
right = null;
data = 0;
}
/* Constructor */
public BSTNode(int data) {
left = null;
right = null;
this.data = data;
}
public BSTNode getLeft() {
return left;
}
public void setLeft(BSTNode left) {
this.left = left;
}
public BSTNode getRight() {
return right;
}
public void setRight(BSTNode right) {
this.right = right;
}
public int getData() {
return data;
}
public void setData(int data) {
this.data = data;
}
}

get average value from a tree of nodes

I have to implement this method:
public int GetAverage(Node root){
//TODO implement
}
this method should get average value of all nodes of root tree. where :
public interface Node {
int getValue();
List<Node> getNodes();
}
do you have any ideas how to implement this method?
thank you
my attempt:
public static double value;
public static int count;
public static double getAverage(Node root) {
count++;
value += root.getValue();
for (Node node : root.getNodes()) {
getAverage(node);
}
return value / count;
}
but how to do it without the static fields outside of the method?
Simply traverse through all nodes and remember the count and the overall sum of all values. Then calculate the average. This is an example written in Java.
public interface INode {
int getValue();
List<INode> getNodes();
}
public class Node implements INode {
private List<INode> children = new ArrayList<INode>();
private int value;
#Override
public int getValue() {
return value;
}
#Override
public List<INode> getNodes() {
return children;
}
public static int getAverage(INode root) {
if (root == null)
return 0;
Counter c = new Counter();
calculateAverage(root, c);
return c.sum / c.count;
}
class Counter {
public int sum;
public int count;
}
private static void calculateAverage(INode root, Counter counter) {
if (root == null)
return;
counter.sum += root.getValue();
counter.count++;
// recursively through all children
for (INode child : root.getNodes())
calculateAverage(child, counter);
}
}
public static double getAverage(Node root) {
Pair p = new Pair(0,0);
algo(root, p);
return ((double) p.element1) / ((double) p.element2);
}
private static void algo(Node root, Pair acc) {
for(Node child : root.getNodes()) {
algo(child, acc);
}
acc.sum += root.getValue();
acc.nbNodes++;
}
With Pair defined as follows:
public class Pair {
public int sum;
public int nbNodes;
public Pair(int elt1, int elt2) {
this.sum = elt1;
this.nbNodes = elt2;
}
}

Resources