Determine average of all Node values within a Tree Structure - java

Given this interface...
public static interface Node
{
int getValue();
List<Node> getChildren();
}
Implement the following method to return the average of all node values in the tree.
public static double getAverage(Node root)
{
}
I'm having an extremely hard time with this practice problem and have a few questions.
I assume this is best completed using recursion, is that correct?
Is this possible without a helper method or global variables?
Is this possible without having to traverse the tree twice? (Once for node sum, once for node count)
Additionally, if someone could provide some psuedo-code, I'd greatly appreciate it.

You can use recursion, but it is possible to solve this problem without it, too. What you need is just a depth-first search. You can implement it iteratively using a stack.
Yes, it is possible. A version with a stack does not require any additional methods.
Yes, it is possible. You can just compute both of these values during one traversal.
Here is a pseudo code of a non-recursive implementation:
valuesSum = 0
nodesCount = 0
stack = new Stack
stack.add(root)
while (!stack.isEmpty())
Node v = stack.poll()
nodesCount++
valuesSum += v.getValue()
for (child : v.getChildren())
stack.add(child)
return valuesSum / nodesCount

Related

Balance a binary search tree

I'm trying to implement a binary search tree class in Java with a method that can rebalance the tree if there's a difference in height. I'm trying to do it by first storing the value of the nodes in an List (an attribute of the class).
I then want to take the middle element of this list and assign this to the root of the tree. After this I take the left- and right part of the list and do the same thing recursively to the left- and right children of the root and so on.
My algorithm doesn't seem to work though and I don't understand what I'm doing wrong. I wonder if someone can take a look at my code and explain what the problem is? What I do is basically pass the ordered list of elements of the tree (an attribute of the class) and the root into the function below:
public void build(BinaryNode<E> n,List<E> list) {
int idx = (int)Math.floor(list.size()/2);
if(n!=null) {
n.element = list.get(idx);
} else if(n==null) {
n = new BinaryNode<E>(list.get(idx));
}
if(!list.subList(0,idx).isEmpty()) {
build(n.left,list.subList(0,idx));
}
if(!list.subList(idx+1,list.size()).isEmpty() ){
build(n.right,list.subList(idx+1,list.size()));
}
return;
}
Kind regards,
Java method calls are "call by value". This means changing a parameter (like n in your case) has no effect outside of the method.
Try to define your method like this
public BinaryNode<E> build(List<E> list) { ... }
Try investigating about AVL tree
Some useful links:
https://en.wikipedia.org/wiki/AVL_tree
https://www.geeksforgeeks.org/avl-tree-set-1-insertion/

How to implement Union-Find using linked lists?

I need to write a piece of code using the Kruskal algorithm, which in turn needs the Union-Find algorithm.
This includes the methods Make-Set(x), Find-Set(x) and Union(x, y).
I need to implement them using linked lists, but I am not sure of how to start with the Make-Set method.
The Make-Set Method should create a set and make the first element into a key (to compare sets). How exactly would I declare a key using linked lists?
Shortly put: How do I implement this pseudo code for linked lists in Java?
Make-Set(x)
x.p = x
x.rank = 0
Thanks for your help in advance!
I've heard this referred to in the past not as "Union-Find" but as a disjoint set. It isn't exactly a linked list, since the nodes do have a link, but they aren't necessarily linked up in a linear fashion. It's more like a tree where each node has a pointer to its parent and you can walk up the tree to the root.
I don't have much time right now, but here's a quick sketch of how I would implement it in Java:
class Disjoint {
Disjoint next;
Disjoint findSet() {
Disjoint head = this;
if (next != null) {
head = next.findSet();
next = head;
}
return head;
}
void union(Disjoint other) {
Disjoint us = this.findSet();
Disjoint them = other.findSet();
us.next = them;
}
}
Creating an instance is your Make-Set. What you call Find-Set I would call find head or find leader, maybe find identity. I've called it findSet here, though. It walks the chain to find the root of the tree. It also performs an optional operation; it snaps all the links on the way back out of the recursive call so that they all point directly at the root. This is an optimization to keep the chains short.
Finally, Union is implemented just by assigning one root's next pointer to point at the other set. I'm not sure what you intended with rank; if it's the size of the set, you can add a field for that and simply sum them when you union two sets. But you initialize it to 0 for a new set when I would expect it to be initialized to 1.
Two nodes a and b belong to the same set if a.findSet() == b.findSet(). If you need the nodes to carry some data, make the class generic and provide the data to the constructor, and add a getter:
class Disjoint<T> {
Disjoint<T> next;
T data;
public Disjoint(final T data) {
this.data = data;
}
public T getData() {
return data;
}
// rest of class identical except Disjoint replaced with Disjoint<T> everywhere
}

Random Postorder traversal in neo4j

I'm trying to create an algorithm in Neo4j using the java API. The algorithm is called GRAIL (http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.169.1656&rep=rep1&type=pdf) and it assigns labels to a graph for later answering reachability queries.
This algorithm uses postorder depth first search but with random traversal each time (each child of a node is visited randomly in each traversal).
In the neo4j java api there is an algorithm doing this (https://github.com/neo4j/neo4j/blob/7f47df8b5d61b0437e39298cd15e840aa1bcfed8/community/kernel/src/main/java/org/neo4j/graphdb/traversal/PostorderDepthFirstSelector.java) without the randomness and i can't seem to find a way to do this.
My code has a traversal description in which i want to add a custom order (BranchOrderingPolicy) in order to achieve the before mentioned algorithm. like this:
.order(**postorderDepthFirst()**)
The answer to my question came rather easy but after a lot of thinking. I just had to alter the path expander (i created my own) which returns the relationhipss that the traversal takes as next and there a simple line of code to randomize the relationships.
The code is :
public class customExpander implements PathExpander {
private final RelationshipType relationshipType;
private final Direction direction;
private final Integer times;
public customExpander (RelationshipType relationshipType, Direction direction ,Integer times)
{
this.relationshipType = relationshipType;
this.direction = direction;
this.times=times;
}
#Override
public Iterable<Relationship> expand(Path path, BranchState state)
{
List<Relationship> results = new ArrayList<Relationship>();
for ( Relationship r : path.endNode().getRelationships( relationshipType, direction ) )
{
results.add( r );
}
Collections.shuffle(results);
}
return results;
}
#Override
public PathExpander<String> reverse()
{
return null;
}
}
There's no such ordering by default in neo4j, however it should be possible to write one. TraversalBranch#next gives the next branch and so your implementation could get all or some and pick at random. However state keeping will be slightly tricky and as memory hungry as a breadth first ordering I'd guess. Neo4j keeps relationships in linked lists per node, so there's no easy way to pick one at random without first gathering all of them.

Get number of descendants at each node in tree in linear time without dynamic programming?

I have written a recursive function that computes the number of descendants at each node in an n-ary tree.
The results of the computation are in the array that is passed in. I am looking for a function that runs in linear time and does not use dynamic programming. The results would ideally be set within each node not requiring a separate data structure. Recursive is preferred if possible.
void setNumberDescendants(Node root, int[] descCount) {
for(Node child:root.children){
setNumberDescendants(child, descCount);
descCount[root.key] += 1+descCount[child.key];
}
}
class Node{
int key;
List<Node> children;
}
Your solution does what you ask for.
It is linear: you only access each node once, and do a constant amount of work for each one.
It does not use dynamic programming: dynamic programming requires a problem to exhibit overlapping subproblems and optimal substructure. This problem does not exhibit overlapping subproblems. Your subproblems, for a set node, consist of the answers for the subtrees rooted at that node. These subtrees do no overlap.
If you want to set the results in each node, simply do something like this:
void setNumberDescendants(Node root) {
for(Node child:root.children){
setNumberDescendants(child);
root.descendants += 1+child.descendants;
}
}
class Node{
int key;
int descendants;
List<Node> children;
}

Calculate the depth of a binary search tree?

I am having difficulty calculating the summation of depths [the sum of the individual depths for all children of the root] for a given BST. I have the total number of nodes for the tree, and I am trying to calculate the average depth for the tree, requiring I have this depth sum.
Recursion and I don't get along very well.. I am finding this problem very difficult. I would like to see a recursive solution though, if possible.
NOTE:
I have created accessors Node.getLeft() and Node.getRight()
You just need to keep a depth counter as you traverse the tree (look up tree traversals if you have to) and add the value of the counter every time you reach a node. Then just divide by the number of nodes.
This looks like homework so I'm not providing a more detailed solution.
Think about how you would go about this canonically by hand if I had presented a picture of a BST to you on a sheet of paper. When you're at a node, what information do you need to keep track of? How does one find the height of a given node?
From here, try to translate this into pseudocode or even straight into Java. If you're having trouble, feel free to comment so users can help you out.
Is this homework? If so tag the question as such.
You could create a method that:
has a node reference and a depth as arguments
increment depth
if node is not a child node call recursively for left and right and update sum accordingly
otherwise return sum + depth
Once you have this devide by the number of children in the tree to get the average depth.
We need to visit all leaf nodes and figure out how deep they are. This suggests:
Give your node-visiting function an extra argument. It needs to know not just where it's going but also how deep it is. Every time it's called, it's called on to go deeper, so your node visitor just has to increment the depth number it got from the caller.
Now one of 2 things can happen:
Either the node you found is a leaf node, i.e. it doesn't have any children; in this case, your visitor needs to return its depth to the caller. Yeah, it just returns the number it got from the caller, + 1.
or it's not a leaf node. In that case, it will have either 1 or 2 children. We need to get those depth reports from our kids back up to the caller, so just return the sum of the depths returned by the children.
By the magic of recursion, the number returned to the root's visitor will be the sum of the depths of all children.
To get an average depth, you'll want to divide this by the number of leaf nodes; which I'd leave to a second traversal to calculate. It could be done in one, but it would be a little more complicated.
Since this is homework, I don't want to just give you an answer. Instead, here's a recursive way to calculate the length of a singly linked list. Hopefully this will demonstrate recursion in a way you can understand, and you can extrapolate from there to solve your BST problem.
public final class LL {
public final int value;
public LL next;
public LL(final int value) {
this.value = value;
}
public void add(final int value) {
if (null == next) {
next = new LL(value);
} else {
next.add(value);
}
}
/**
* Calculate the length of the linked list with this node as its head (includes this node in the count).
*
* #return the length.
*/
public int length() {
if (null == next) {
return 1;
}
return 1 + next.length();
}
public static void main(final String... args) {
final LL head = new LL(1);
head.add(2);
head.add(3);
System.out.println(head.length());
System.out.println(head.next.length());
}
}

Categories