In order to do level order(BFS) traversal of a generic tree I wrote the following display function for the code mentioned in the link below. The problem is that each level is printed twice. Can someone tell me why.
Original Code without this function can be found in the link below in case someone need the entire implementation else just look at the displayBFS function below and tell me why are values repeating
Level Order traversal of a generic tree(n-ary tree) in java
Thanks!
void displayBFS(NaryTreeNode n)
{
Queue<NaryTreeNode> q = new LinkedList<NaryTreeNode>();
if(n!=null)
{
q.add(n);
System.out.println(n.data);
}
while(n!=null)
{
for(NaryTreeNode x:n.nary_list)
{
q.add(x);
System.out.println(x.data );
}
n = q.poll();
}
}
Current Tree Structure for reference:
root(100)
/ | \
90 50 70
/ \
20 30 200 300
Output:
100
90
50
70
90
50
70
20
30
200
300
20
30
200
300
The problem is that you process your root-node twice: you initially add it to your queue (in the line q.add(n)), then you process it before you first get to n = q.poll(), and then you get it off the queue and process it again.
Everything else is correct, which is why you only get two copies of each non-root node: the doubling only occurs once, at root.
To fix this, either remove the line q.add(n) (since you process the root node anyway, even without it), or else change this:
while(n!=null)
{
...
n = q.poll();
}
to this:
while((n = q.poll()) != null)
{
...
}
so that you don't process the root node that initial extra time.
Related
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
I am trying to understand the concept of recursion. I understand how it works if there is one recursive statement in the code (example factorial)
I dont understand how code like this to calculate the depth of a binary tree would work:
public int getDepth(Node root)
{
if ( root == null) return 0;
int left = getDepth(root.left);
int right = getDepth(root.right);
if (left > right)
return left + 1;
else
return right + 1;
}
I see why this works but not how. Can someone explain to me how the second recursive call (getDepth(root.right)) works? What would this code look like in the memory? When getDepth(root.left) is recursive called does that stack ever go to the if statement at the every bottom?
What happens is that each consecutive call to getDepth is completely separate and thus the bound variables are separate and it follows it's arguments and is oblivious that it's called from a version of itself with different arguments.
When you do getDepth(null) you get 0 since it's the very base case on the first line. However if you send it getDepth(new Node(null, null)) it will call getDepth(root.left) which is the same as getDepth(null) and turns into 0 for both left and right and the result is 0 + 1.
If you would bind the previous node to a variable node and try getDepth(new Node(node, node)) it will do both left and right again where both of them would be the answer of the previous test 1. The result would be 1 + 1, thus 2.
You can continue like this and just assume the result based on the previous calculations. By looking from a complex argument you need to imagine that each consecutive recursion starts fresh with it's arguments and that follows the same pattern. When a result is passed back the caller continues to the next line. In a tree structure like:
1
/ \
2 3
/\ /\
4 5 6 7
I just numbered the nodes and not included null nodes. You'll see the execution goes in this order. Identation indicates stack depth / how many calls are waiting to be resumed.
getDepth(1)
getDepth(2) // left
getDepth(4) // left
getDepth(null) // left base
getDepth(null) // right base
return 0
getDepth(5) // right
getDepth(null) // left base
getDepth(null) // right base
return 0
return 0 + 1;
getDepth(3) // right
getDepth(6) // left
getDepth(null) // left base
getDepth(null) // right base
return 0
getDepth(7) // right
getDepth(null) // left base
getDepth(null) // right base
return 0
return 0 + 1;
return 1 + 1;
return 2 + 1;
Try to trace the execution if the tree consisted of only a single node (just the root node).
The stack would look something like this when getDepth(root.left) is called:
--->getDepth(root.left) //this will return 0 immediately, and will be popped of the stack
getDepth(root) // this is your entry point
once, getDepth(root.left) returns, the stack looks like this:
--->getDepth(root) // this is your entry point
then the method at the top of the stack now will continue it's execution from where it was (it will now call getDepth(root.right), and the stack will look like this:
--->getDepth(root.right) //this will return 0 immediately, and will be popped of the stack
getDepth(root) // this is your entry point
again, once getDepth(root.right) returns, it will be popped off the stack and the calling method will continue it's execution and will then execute the last if statement.
The same pattern of execution will be followed for a tree with multiple nodes: eventually the recursive method calls will return (unless there is an exception) and the calling method will continue it's execution from the next statement.
private Node put(Node x, Float longitude, Float latitude, String place, String address) {
if (x == null)
return new Node(longitude, latitude, place, address, 1);
int cmpX = longitude.compareTo(x.longitude);
int cmpY = latitude.compareTo(x.latitude);
if (cmpX < 0 | (cmpX == 0 && cmpY < 0)) {
if (x.left == null) { x.left = new Node(longitude, latitude, place, address, x.N);}
else{x.left = put(x.left, longitude, latitude, place, address);}
} else if (cmpX >= 0) {
if (x.right == null) { x.right = new Node(longitude, latitude, place, address, x.N);}
else{x.right = put(x.right, longitude, latitude, place, address);}
}
x.N = 1 + size(x.left) + size(x.right);
return x;
}
I have this code that I'm try to use to insert into a BST and it works for the first 3000 or so elements, before causing a StackOverFlow error. How do I prevent this from happening?
The reason that you encountered a StackOverflowError is that you inserted your items in an order that was already sorted. Let's see what happens in this case. I'll use integers, even though you have more complicated objects, for simplicity in seeing what happens.
After inserting 1:
Root(1)
After inserting 2:
Root(1)
\
(2)
After inserting 3:
Root(1)
\
(2)
\
(3)
After inserting n:
Root(1)
\
(2)
\
...
\
(n)
You implemented put as a recursive method. Because of that, when you have added 3000 elements, and you're attempting to add a 3001st element, you need to recur 3000 times, and now there are 3000 copies of put on the call stack, about where you say it overflows.
You can convert put into an iterative method, using a while loop instead of recursion. This will eliminate the StackOverflowError, but it won't solve the root (so to speak) of the problem -- that your BST looks like a linked list.
You can submit your elements in a random order. It may look like this:
Root(1123)
/ \
(799) (2800)
/ \ / \
(64) (999) (1599) (2901)
It may not be properly balanced, but most likely it will not devolve into the linked list situation you have from inserting in sorted order.
You can perform rotations about a specific node when one branch gets too large compared to the other branch. If you're feeling adventurous, you can implement a red-black tree, a BST that uses rotations to keep the tree balanced "enough".
I have some java code that compares two files. When it finds similar numbers on a particular line it prints that line to a new file. This seems to work for a good amount of time... Until what I believe is the last line. That line only ever gets partially printed. I THINK that it might be because of a 'break' that is later in the code, but I looked around on google and wasn't really sure if any of the answers were really relevant.
Here is some code that I think is related:
Read in files
while the line isn't null...
Parse files
Write a header
Some comparisons
while (!input.startsWith("#") && !input.startsWith("P")) {
prse = input.split("\t");//split the file by tabs
pos = prse[7];
poson = prse[8];
pos = Integer.parseInt(poson);
if (cnt < num.size()) { //if we haven't exceeded an array
if (num.get(cnt).equals(pos)) { //if the first number is the same
if (cnt2 < posstart.size()) { //if we haven't exceeded another array
end = Integer.parseInt(posend.get(cnt2)); //change to int
start = Integer.parseInt(posstart.get(cnt2));//change to int
if (pos < start) { //if it is less then the starting pos then it can't fall within
break; //so break
}
if (pos < end && pos > start) {//I am trying to see if a number falls within the range of numbers from a separate file
out1.write(input + "\n"); //If it does: This is where I am writing out the line
break; //if I remove this break the program hangs here
} else {
cnt2++; //if it wasn't the same, add
}
}
} else {
cnt++; //if it was the same move to the next one
cnt2 = 0; //reset this number
break; //go back to beginning
}
} else {
break;
}
So the code works perfectly for about 6500 lines but then it abruptly cuts off the last line:
Blah B 6 5 8 C 5 X 6
Blah A 0 1 4 C 2 X 7
Blah B 3 5 9 C 5 X 6
Blah B 0 9 4
Does anyone know what I can add to stop the final line from cutting off so suddenly? I know in BASH you could specify for it to wait... But I was confused by the java equivalents and was hoping someone could suggest one for me and help to explain it a bit better.
For the sake of having an answer (until Carl puts his up) I am going to go ahead and answer
did you close the outputstream? maybe you need to call the flush method. – Carl
He was right. I hadn't. Silly me.
Actually, i made that mistakes a lot, i think it is because with the garbage collector,we don't really care about memory management,so,it tends to forget to close any iostream we'd opened or to flush memory to disk.That's a terrible thing to do though.
I want to know the code to print a binary tree level by level, I mean, if I have this tree:
5
/ \
3 2
/ \
4 6
I want to print it like: 5 3 2 4 6.
I know I need to do the tree depth method and I already did it, but I don't know what else to do.
You can use the level traversal algorithm to print them.
The algorithm works as follows:
queue := < root >
while queue is not empty
v := queue.front
print v
foreach s : s is a son of v
queue.enqueue(s)
queue.dequeue
Okay, I think I figured it out:
1. extend the class Node and add a property called height (int)
2. Calculate the height of each node of the tree (easy recursive function - no data-structure is needed)
3. use a for-loop, and run in-order traversal, for each height (level) and print the nodes of that level
public void displayByLevel(){
ArrayList<Node> ar = new ArrayList<>();
ar.add(root);
displayByLevelHelper(ar);
}
private void displayByLevelHelper(ArrayList<Node> ar){
if(ar.isEmpty()){
return;
}
ArrayList<Node> nextAr= new ArrayList<>();
for(Node n:ar){
System.out.print(n.data + " ");
if(n.left!=null){
nextAr.add(n.left);
}
if(n.right!=null){
nextAr.add(n.right);
}
}
System.out.println();
displayByLevelHelper(nextAr);
}