Java: For Loop stops after one element in a recursive function - java

I am building a tree structure in java from scratch. For getting the height of my tree I am using a recursive function.
Each note (IP) contains a list of all connections it has, including there parent. My idea was to loop over all children and call the height function again when it's not the parent.
My problem is, that it only calls one child and does not loop over all possible children. Maybe someone can tell me where is my fault.
If one Note has two children and each of them also has another two. It only views the first one at both iterations.
public int recursiveGetHight(final Node node, Node parent) {
Node viewPoint = getViewPoint(node);
int h = 0;
for (Node child : viewPoint.getChildren()) {
if (child.getChildren().size() <= 1) {
return 0;
} else if(parent == null || child.getValue() != parent.getValue()){
h = recursiveGetHight(child, viewPoint) + 1;
return h;
}
}
return h;
}
Exempel:
root
- note 1
- sub note 1
- sub note 2
- x
- y
- note 2
- sub note 1
- z
- sub note 2
int h = recurisvHeight(root, null)
result should be 3 but the function returns 2.
If I at a print command inside the for loop
System.out.println(child);
it shows:
note1
sub note 1

It's because you use return, when you make a return your function end.
You have to remove the first return = 0 and make an ArrayList of child and replace return h in the by loop by append the child in the list.

Related

Binary Tree In Order creation using Arithmetic Expression Queue

I'm trying to implement code that takes a queue, titled 'input,' that has an arithmetic expression.
The expression looks like this:
5 - a * 6 + b
This expression is stored into a queue and I have a method that checks the type of whatever I'm popping in my queue. The method is called getIt() and it returns an integer that tells if it is either an operand or operator. 1 is equal to an operand; 0 is equal to operator. So if I call queue.pop() which should return the value pop the value '5', the getIt() method call on that pop would return 1.
I have an add method that takes in a queue and is supposed to add the values of the queue into a binary tree using the in order system.
BinNode<Term> current = new BinNode<>();
BinNode<Term> parent = new BinNode<>();
current = null;
parent = null;
for (int i = 0; i < input.size(); i++) {
if (input.pop().getType() == 1) {
current = new BinNode<Term>(input.pop());
} else if (input.pop().getType() == 0) {
parent = new BinNode<Term>(input.pop());
parent.setLeft(current);
}
}
In this code, I create two nodes called current/parent. I created a loop that would iterate through the queue, check to see if a popped value would be an operand-- if yes, then I set the current node to that popped value. If it's an operator, I set that to the parent node and set the left node to current. My issue here is how I finish the tree. If the goal of the tree is to make it appear similar to
*
/ \
- +
/ \ / \
5 a 6 b
I dont know how I can get my code to reflect this.

Parse Java code with JavaParser and find the statement type of parent nodes

I have made a small program that uses JavaParser [1] to parse Java code and identify the types of statements that appear in the code. This has been implemented successfully. What I want to do next, and is a bit tricky, is to find the parent node for an if-statement, and check whether the first statement of the parent node is a while-loop. After confirming that the above statement is true, I also want to find if this if-statement is the last child of the parent node.
Following you can find an example of the above description:
void example() {
int x = 1;
int y = 1;
while (y < 3) {
while (x < 4) {
x++;
}
if (y < 5) {
y++;
}
}
x = 0;
}
The main question I have with parsing the above code, is how to obtain that the parent node of if (y < 5 ) is a while-loop (while (y < 3)) and secondly, which might be even trickier, is how to identify that the if-statement of this example is the last statement before we skip back to the parent loop. There is also y++; inside the if but it might be skipped if the condition of the if is not true, so I do not want to consider it as the last child of the parent node. I believe what I should do is to check for the last "neighbour"? What I mean by neighbour is the relationship between the second while and the if of this example, i.e. they are at the same level.
My thoughts so far implemented:
//find if the if-statement has a parent node
if (currIf.getParentNode().isPresent()) {
//find if the parent Node is a While loop
Optional<Node> parent = currIf.getParentNode();
parent.get().getBegin();
}
With the above code I am able to check if the if-statement has a parent node and I can find the location of the first while but I do not know how to confirm that it is a while statement and also implement the second described part.
UPDATE:
I managed to find how to check if the parent is a while-loop and currently trying to find a solution on how to identify that the if-statement is the last statement of its level (or hierarchy if you prefer).
Optional<WhileStmt> ifParent = currIf.findAncestor(WhileStmt.class);
//find if the if-statement has a parent node
if (ifParent.isPresent()) {
//find if the parent Node is a While loop
Optional<Node> sameNode = ifParent.get().findFirst(Node.class, n -> n == currIf);
if (sameNode.isPresent()) {
System.out.println(sameNode);
}
}
Your update could give you the wrong result if I am understanding it correctly. Yes, your solution will work if a WhileStmt is the parent, but it also could give you a WhileStmt a bit further up the tree.
Why can't you do something like the following?
boolean parentIsWhileLoop = ifStmtNode.getParent() instanceof WhileStmt;
For determining if the ifStmt is the last node, you could do
Node ifStmtParent = ifStmt.getParent();
List<Node> ifStmtSibilings = ifStmtParent.getChildNodes();
Node lastNode = ifStmtSiblings.get(ifStmtSiblings.size() - 1);
boolean ifStmtIsLast = lastNode == ifStmt;

Understanding Binary Search Tree Counting

I am having trouble understanding how this Binary Search Tree method is counting nodes, I have looked at many examples online, however I cannot find one which will explain exactly what is happening.
Here is an example:
public int nodes() {
int leftNodes = 0;
if (left != null) {
leftNodes = left.nodes();
}
int rightNodes = 0;
if (right != null) {
rightNodes = right.nodes();
}
return leftNodes + rightNodes + 1;
}
This is how I am understanding the process of this method, and maybe someone can help me understand where I'm going wrong.
The method is called from outside of itself from a BTS Object; "tree.nodes() etc".
int leftNodes is declared and set to 0.
If there is a left node (assume there is), then the value of leftNodes will be assigned to the return value of the call to nodes();
The recursive call will go through the nodes method again, assigning leftNodes to zero again.
So what I don't understand is where is the leftNodes variable being incremented? It seems like it's just recursing through the method again but the value doesn't change, and from how I see leftNodes and rightNodes will always be 0.
I found another example of BTS counting, this one using C++
int CountNodes(node*root)
{
if(root==NULL)
return 0;
if(root->left!=NULL)
{
n=n+1;
n=CountNodes(root->left);
}
if(root->right!=NULL)
{
n=n+1;
n=CountNodes(root->right);
}
return n;
}
I find this method much easier to follow, as n is clearly being incremented everytime a node is found.
My question is how is the leftNodes/rightNodes value being incremented in the recursive call?
You should think about the end of the recursion.
Suppose you have a single node with no children.
Both left and right would be null, so you will make no recursive calls.
You'll return
leftNodes + rightNodes + 1; // 0 + 0 + 1 == 1
Now, suppose you have a simple tree that consists of a root, a left child and a right child.
When you call nodes() for the root of that tree, both left and right are not null, so we'll call both left.nodes() and right.nodes(). Since both the left and right children are leaf nodes (i.e. they have no children), the recursive calls for both will return 1, as explained above.
Therefore, when the recursive calls return, we'll return
leftNodes + rightNodes + 1; // 1 + 1 + 1 == 3
which is the number of nodes in our tree.
The variables leftNodes and rightNodes are local to the method nodes() which means that there is a different instance of these variables for each call of the method.
So when you call recursively the method (with left.nodes() for instance), the value of leftNodes is the same before and after the recursive call because it (the call) will have it's one instance of leftNodes (and rightNodes).
This is a basic implementation of inorder traversal. For each node it goes to left child until there is no left child remaining (Because of recursion, think like in each visit of a node it is pushed to a stack). Then it repeats the same procedure for the top of the stack until there is no element left in the stack (Again note that, Stack is used to make things simpler compared to recursion). While doing so, it basically increments the total sum by one for each node it visits.

Why does my code for counting the knots of a tree work?

I'm facing the classic "It works, but I don't know why!"-problem. I just applied a principle that I knew from another excercise with integers, but here I have to work with trees. The testing of the method was successfull. I am supposed to count the knots of a tree, and I do this bis traversing through it (in this case: inorder), and every time I traverse successfully (meaning: not facing an empty sub-tree), I count that as a knot. In this case, I'm wondering why this code doesn't count too much knots. For example, when I always go left and face an empty sub-tree, wouldn't I go up until I reach a knot where I can go right? Why does my code avoid this kind of problem?
public static int numberKnots (Tree b) {
int count = 0;
if (b.empty()) {
return 0;
}
else {
traverse.inorder(b.left());
traverse.inorder(b.right());
count = 1;
}
return count + numberKnots(b.left()) + numberKnots(b.right());
}
You do not really travel up and down the tree, you only travel down and visit each node once, and you do this by making your trees More and more simple.
Consider The following tree
a
/ \
b c
/ \
d e
So you start from the root and check if it is empty which it is not, so you return the result of 1 + numberKnots(left) + numberKnots(right). left and right are also trees and they are simpler than a
left right
b c
/ \
d e
So now you check the b tree, which is empty so it just returns 0. Then you check the c tree, which is not empty so you return 1 + countKnots(left (of c)) + countKnots(right (of c)) and so on.
Each step of the calculation would be:
countKnots(a)
= 1 + countKnots(b) + countKnots(c)
= 1 + 0 + countKnots(c)
= 1 + 0 + 1 + countKnots(d) + countKnots(e)
= 1 + 0 + 1 + 0 + countKnots(e)
= 1 + 0 + 1 + 0 + 0
= 2
Your code could be simplified to
public static int numberKnots (Tree b) {
if (b.empty()) {
return 0;
} else {
return 1 + numberKnots(b.left()) + numberKnots(b.right());
}
}
However, it does not seem to handle tree nodes which does not contain both left and right nodes, so the following tree would cause an error
a
\
c
Since you are using recursion,it does not transverse the same node twice.So your code works perfectly fine.consider (A) has two child nodes (B)&(C) further (B) has two childs (B1)&(B2).when transversing through recursion,it usses stack."(consider s to be our stack)". First the control reaches node(A) and since it has left child (A) is pushed into stack and control is trasferred to (B) now control is trasferred to (B)'s left child(B1) and (B) is pushed into stack, since (B1) does not have any childs it is counted and control is trasferred to top of stack i.e (B) and (B) is counted now control is trasffered to (B)'s right child it (B2)and (B2) is counted and control is trasferred to (B).Now (B) does not have any part of code left thus it is popped from stack and control is trasfered to (A) and (A) is counted and control is transfered to its right child (c).Similarly all nodes are counted without duplicating.
Hope it helps

Restore heap condition throughout the entire heap

I'm trying to answer the following programming question:
In the heap.java program, the insert() method inserts a new node in the heap and ensures the heap condition is preserved. Write a toss() method that places a new node in the heap array without attempting to maintain the heap condition. (Perhaps each new item can simply be placed at the end of the array.) Then write a restoreHeap() method that restores the heap condition throughout the entire heap. Using toss() repeatedly followed by a single restoreHeap() is more efficient than using insert() repeatedly when a large amount of data must be inserted at one time. See the description of heapsort for clues. To test your program, insert a few items, toss in some more, and then restore the heap.
I've written the code for the toss function which successfully inserts the node at the end and doesn't modify the heap condition. I'm having problems with the restoreHeap function though and I can't wrap my head around it. I've included the two functions below.
The full code of heap.java is here (includes toss() and restoreHeap() )
toss() - I based this off the insert function
public boolean toss(int key)
{
if(currentSize==maxSize)
return false;
Node newNode = new Node(key);
heapArray[currentSize] = newNode;
currentSize++;
return true;
} // end toss()
restoreHeap() - I based this off the trickleUp function and I'm getting a StackOverflowError.
public void restoreHeap(int index)
{
int parent = (index-1) / 2;
Node bottom = heapArray[index];
while( index > 0 &&
heapArray[parent].getKey() < bottom.getKey() )
{
heapArray[index] = heapArray[parent]; // move it down
index = parent;
parent = (parent-1) / 2;
} // end while
heapArray[index] = bottom;
while(index != 0)
{
restoreHeap(parent++);
}
} // end restoreHeap()
Any ideas? Help appreciated.
I'll give it a shot. Here is a way to do what you asked with some explanation.
Since you know that half of all nodes in a heap are leafs and a leaf, by itself, is a valid heap, you only have to run through the other half of the nodes to make sure they also are valid. If we do this from the bottom and up, we can maintain a valid heap structure "below" as we go up through the heap. This can easily be accomplished by a for loop:
public void rebuildHeap()
{
int half = heapArray.length / 2;
for(int i = half; i >= 0; i--)
restoreHeap(i);
}
How is restoreHeap implemented then?
It's supposed to check the node at index against its children to see if it needs to relocate the node. Because we make sure that the trees below the index node are heaps, we only have to move the index node to the right position. Hence we move it down in the tree.
First we need to locate the children. Since each row in the three have twice as many nodes as the row before, the children can be located like this:
private void restoreHeap(int index)
{
int leftChild = (index * 2) + 1; //+1 because arrays start at 0
int rightChild = leftChild +1;
...
Now you just have to compare the childrens value against your index nodes value. If a child have a bigger value you need to swap the index node with the child node. If both children have a bigger value, you need to swap with the child with the biggest value of the two (to maintain the heap structure after the swap). When the nodes have been swapped you need to call the method again to see if you need to move the index node further down the tree.
...
int biggest = index;
if(leftChild < currentSize && heapArray[leftChild].getKey() > heapArray[index].getKey())
biggest = leftChild; //LeftChild is bigger
if(rightChild < currentSize && heapArray[rightChild].getKey() > heapArray[biggest].getKey())
biggest = rightChild; //RightChild is bigger than both leftChild and the index node
if(biggest != index) //If a swap is needed
{
//Swap
Node swapper = heapArray[biggest];
heapArray[biggest] = heapArray[index];
heapArray[index] = swapper;
restoreHeap(biggest);
}
}

Categories