DFS a tree with no memory - java

I'm trying to write a function to traverse a tree with depth first search.
My current algorithm goes something like:
If children
go to first child
If no children
go to next sibling
If no siblings
go to parent
The problem I'm running into is that I can't mark nodes on the tree as having been visited, so when I go to the parent the cycle just resets and it goes to the child again, getting stuck in a loop. Does anyone have any idea as to how I could solve this?
(It's in java using the ANTLR plugin)
EDIT:
Following one of the suggestions I wrote this:
public void traverseTree(Tree tree){
if (tree.getChildCount() > 0){
tree = tree.getChild(0);
traverseTree(tree);
System.out.println(tree.toString());
}
if (tree.getParent().getChild(tree.getChildIndex() + 1) != null){
tree = tree.getParent().getChild(tree.getChildIndex() + 1);
traverseTree(tree);
System.out.println(tree.toString());
}
if (!tree.getParent().toString().contains("ROOT_NODE")){
tree = tree.getParent();
traverseTree(tree);
System.out.println(tree.toString());
}
}
Root node is the name of the root node, but I'm getting a stack overflow error. Anyone have any idea why?
Thanks.

I would use recursion in this case.
class Node {
public List<Node> getChildren() { .... }
public void traverse(Visitor<Node> visitor) {
// If children
// go to first child - by traversing the children first.
for(Node kid: getChildren())
kid.traverse(visitor);
// If no children
// go to next sibling, - by continuing the loop.
visitor.visit(this);
// If no siblings
// go to parent - by returning and letting the parent be processed
}
}
interface Vistor<N> {
public void visit(N n);
}

Using a hash_table map each vertex to boolean indicate whether visited or not

Write a depth first Iterator that keeps track of visited nodes internally. That way the tree doesn't have to change to know that it's being watched.

If "no memory" can be interpreted as O(1) memory, then the change may help:
Remember not only the current node, but also node where you came from
Traverse children only if you didn't came from one of them

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/

Java find the route of seeking node in a tree

public List<Person> getDiseaseRouteTo(Person c){
if(this.contains(c)){
if(root == c){
route.add(c);
}
else if(root != c){
route.add(root);
for(DiseaseTree dt: children){
if(dt.contains(c)){
route.add(dt.root);
dt.getDiseaseRouteTo(c);
}
}
}
return route;
}
return null;
}
The constructor is a tree constructor named DiseaseTree which contain a root node and a Children set. The children set is a DiseaseTree set. I am supposed to find the route of seeking one node. For example, I have an existed tree named ddtt and I want to find the route to find node c in this tree. ddtt.getDiseaseroute(c) will get a list to find node c. like[A, B, C] if tree is like
A
--B
----C
I used recursion to realize that. But it can't have complete route. I don't know what is going on and totally confused.
you are adding the root twice to the route list, once on the line "route.add(root);" and the second time when you go over his children "route.add(dt.root);". you don't need to add it twice.
Also next time try to debug it with a simple input and see what is going on.

Returning a value early from a recursive function

I have a tree of nodes. While iterating this tree depth first, I need to return the list of all duplicate nodes from the root node to my current node.
Due to some business requirements the "already traversed" part of the tree is never the same. I do a lot of swap/replaces of branches in the already traversed part of the tree. So maintaining a list of traversed nodes might not work as it needs updates every time I finish traversing a node.
So whenever I need to answer getDuplicateNodesOfMyCurrentNode() I need to start from the top of the tree (rootNode) and search depth-first till my currentNode and return back a list<Nodes> that are duplicates of my currentNode.
private void getDuplicateNodesOfMyCurrentNode(Node parentNode, Node currentNode,List<Node> dupNodes){
for(Node child: parentNode.getChildren()){
if(child == currentNode){
return;
}
if(child.getApp().equals(currentNode.getApp()){
dupNodes.add(child);
}
getDuplicateNodesOfMyCurrentNode( child, currentNode, aDupNodes);
}
As you guys already know the issue with this code, return doesn't return back the control to the caller of this API since it recursively calls itself.
I want some way to exit out of this recursive loop once I get to my currentNode.
I probably can achieve this by maintaining some boolean state, but want to know the better way of solving this.
Pass whether or not to abort your recursion back through the call stack via a boolean and abandon the current for loop if necessary at the point of the recursive call (also acknowledging Norbet van Nobelen's comment above that alludes to something similar):
private boolean getDuplicateNodesOfMyCurrentNode(Node parentNode, Node currentNode,List<Node> dupNodes){
for(Node child: parentNode.getChildren()){
if(child == currentNode){
return false;
}
if(child.getApp().equals(currentNode.getApp()){
dupNodes.add(child);
}
if (getDuplicateNodesOfMyCurrentNode( builtOn, currentNode, aDupNodes) == false){
return false;
}
}
return true;
}

How to calculate leaf nodes in a nested data structure in Java?

I have a structure like this of what we'll call Box objects.
Box--+---Box----Box
|
+---Box-+--Box
|
+--Box
|
+--Box
I'm trying to ask the top box object for a list of the leaf node Boxes, which is the 3 box objects in this case.
The box object has a list of its children in an instance variable of type Vector called children.
The number of children can be unlimited.
I've been trying to write a single recursive method to do this, but without success.
One way to do this would be a recursive traversal of the structure. The idea is as follows:
There are no leaf nodes in the empty tree.
In a tree with root r with no children, then r is the only leaf.
In a tree with root r, if r has children, then the leaves of the tree are the leaves of those children.
You could write a recursive traversal with this sort of pseudocode:
void findChildren (Box current, List<Box> found) {
/* Case 1. */
if (current == null) return;
/* Case 2. */
if (current.children.isEmpty()) {
found.add(current);
return;
}
/* Case 3. */
for (Box child: current.children)
findChildren(child, found);
}
Hope this helps!
it has been awhile since I've done Java, so I'm sure this code has plenty of syntax errors, and I hope no one marks me down for it; just trying to give you some algorithm ideas. Hopefully it helps:
vector<Box> getLeaves(Box root)
{
vector<Box> tempList; //vector to hold nodes to check
vector<Box> tempList2; //vector to hold nodes' children
vector<Box> leafList;
bool goflag = true;
tempList.add(root);
while(goflag){
for(int i = 0; i < tempList.size; i++){
if(tempList[i].children.isEmpty()){
leafList.add(tempList[i]);
}
else{
//add all children to tempList2
for(int c = 0; c < tempList[i].children.size; c++){
tempList2.add(tempList[i].children[c])
}
}
if(tempList2.isEmpty()) //no more childs
goflag = false;
else
tempList = tempList2;
tempList2.clear();
}
return leafList;
}
It goes through all the nodes, adding children to the next list to check, and adding leaves to a list to be returned.
There are several ways to write such a function. Here's one approach to work through.
Define a helper function that takes a node and a mutable queue holding nodes.
In that helper function, check if the supplied node's children are empty. If so, add that node to the queue, and return.
If instead the supplied node has any children, call the helper function once for each of the children, passing the child and the same queue reference through.
At the top level, create an empty queue, and call the helper function, passing in the root node and the queue.
When the helper function returns, the queue contains all the leaves in the order they were discovered.
A different approach uses the same depth-first traversal, but the function would return the list of leaves it discovered. These lists would need to be combined for each set of siblings explored, working back up the tree as each function call returns.

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