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);
}
Related
I have an input String in the form "(x5(y8)2)4"
Let's say x and y are separate functions, I either want to call them 'n' times, or expand the brackets to create a new String that I can use to call the functions.
Example 1:
Input: (x5(y8)2)4
Output: x5y8y8x5y8y8x5y8y8x5y8y8
Example 2 (more complex):
Input: (((x1)3x2)4y5)2z5
Output: x1x1x1x2x1x1x1x2x1x1x1x2x1x1x1x2y5x1x1x1x2x1x1x1x2x1x1x1x2x1x1x1x2y5z5
Thanks
You could parse the tree to a tree-data-structure. Each node in the tree in the has a number of children nodes. A node could either be a leaf (which is a node without children) - so for example a variable x5 - or it could be a node (with children nodes) which represents a "mathematical" function.
The tree from your first example could look like this.
Root [NODE]:
child_of_root * 4
Child_of_Root [NODE]:
1_child_of_child_of_root + 2_child_of_child_of_root
1_Child_of_Child_of_Root [LEAF]:
x5
2_Child_of_Child_of_Root [NODE]:
child_of_2_child_of_child_of_root * 2
Child_of_2_Child_of_Child_of_Root [LEAF]:
y8
To parse your input-string to the tree-structure you have to analyse how the ( and ) are set and if you "multiply" those by a factor and if you add other stuff - (x5 "+" (y8) "*" 2). This could get quite complicated. (Maybe you could use stacks? However, I'm sure there are tutorials out there).
After you created your tree-representation of your input, it is relatively simple to calculate your output string. Create a recursive algorithm similar to this:
String getReult() {
if(this == NODE) {
return calculate(MY_NODE_CHILDREN.getResult());
}else if(this == LEAF) {
return VARIABLE;
}
}
This is pseudo-code!
The calculate function should add the children string results, multiply them by a factor or do nothing, depending on a context.
If you call your recursive function at the root, the correct result should pop out.
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
Im writing the method to print a binary search tree in order. I figured out a way to do this but it requires either the deletion or nullify nodes as they are printed. Below is my code:
public String printKeysInOrder() {
String output = "";
if (isEmpty()) return "()";
else{
int i = 0;
while(i!=size()){
Node x = root;
int loopBreak = 0;
while(loopBreak!=1){
if(x.left != null) x = x.left;
else if (x.right != null){
output = output + " " + x.val;
x.key = null;
x = x.right;
i++;
}
else{
output = output + " " + x.val;
x.key = null;
loopBreak = 1;
}
}
i++;
}
}
return output;
}
for the tree:
_7_
/ \
_3_ 8
/ \
1 6
\ /
2 4
\
5
it should print "1 2 3 4 5 6 7 8"
the code works in a way that it favors moving left through the tree until it can no longer go left, it then stores that node's value in the string output, makes the nodes key equal to null (as so future iterations of the loop do not go down that tree) and moves right if possible or iterates back around the loop.
Although i'm having trouble making it so the node equals null, as when the code is executed (via junit test) the code doesnt recognize that null key and goes through that subtree anyway? Can anyone help me out or tell me how to make it so the x.left and x.right pointers on future iterations recognize the node as null?
You don't need to nullify or delete nodes you need a traversal algorithm.
The in-order traversal provided here should work without major modification:
http://www.javabeat.net/binary-search-tree-traversal-java/
Another object-oriented approach to this is a Visitor supplied to an in-order traversable which allows you to supply the action performed at each node whether it be printing, collecting, mapping, or something else.
I know how to calculate the diameter of tree but I want to print all possible diameters of tree. Taking the below example:-
1
/ \
2 3
/ / \
4 5 6
All Possible diameters in above tree are:-
First: 4 2 1 3 5
Second: 4 2 1 3 6
Any help regarding approach will very helpful.
I assume you mean all possible paths of maximal length from one leaf to another?
Recursion may be your best bet - in pseudocode something like:
path(startNode, endNode) {
if startNode = endNode return;
for each possible next node n {
add n to your path;
path(n, endNode);
}
}
You could call this for each pair of leaves then throwaway any non-maximal length paths, or perhaps choose which leaves to call this on in a bit more of a smart way, which I would leave up to you
How is this done in graphs:
Run BFS from any node n to find most distant node (from that node) n'
Run BFS from node n' to his most distant node n''
The path from n' to n'' is the tree diameter
So, looking at a tree (which can be unrolled into a graph):
A diameter path goes from any leaf on the lowest level in the left sub-tree to any leaf on the lowest level in the right sub-tree.
Now, since you don't don't magically know which 2 nodes are the end nodes of a diameter, and you only have parent-to-child links, the above algorithm wont work, per se. However, you can use the analogy to build one that works on trees instead of graphs.
OK, here is some quick code you can use (it may not be optimal, but it works)
public class BinarySearchTree {
...
public Iterable<T> diameter() {
if (this.root == null) {
return null;
}
Deque<T> diameterLeftPart = new ArrayDeque<T>();
Deque<T> diameterRightPart = new ArrayDeque<T>();
diameter(this.root.left, diameterLeftPart);
diameter(this.root.right, diameterRightPart);
Deque<T> diameter = new ArrayDeque<T>();
for (Iterator<T> it = diameterLeftPart.iterator(); it.hasNext();) {
diameter.offerLast(it.next());
}
diameter.offerLast(this.root.item);
for (Iterator<T> it = diameterRightPart.descendingIterator(); it.hasNext();) {
diameter.offerLast(it.next());
}
return diameter;
}
private void diameter(Node node, Deque<T> diameter) {
if (node == null) {
return;
}
Deque<T> leftPart = new ArrayDeque<T>();
Deque<T> rightPart = new ArrayDeque<T>();
diameter(node.left, leftPart);
diameter(node.right, rightPart);
if (leftPart.size() > rightPart.size()) {
diameter.addAll(leftPart);
} else {
diameter.addAll(rightPart);
}
diameter.offerLast(node.item);
}
...
}
And the runner class:
public class TreeDiameter {
public static void main(String[] args) {
Tree<Integer> tree = new BinarySearchTree<Integer>();
tree.add(5);
tree.add(2);
tree.add(8);
tree.add(1);
tree.add(3);
tree.add(7);
tree.add(9);
tree.add(4);
tree.add(6);
for (Integer diameterNode : tree.diameter()) {
System.out.print(diameterNode + " ");
}
}
}
With the following output:
4 3 2 5 8 7 6
Quick explanation:
We know that the root is the integral part of the diameter path.
So, we want to get the longest path in the left sub-tree and the longest path in the right sub-tree.
Glued together, they create a diameter.
Using recursive calls diameter(node.left, leftPart) and diameter(node.right, rightPart), leftPart and rightPart contain longest paths in left and right sub-trees, respectively.
Simply comparing their sizes gives us the indication which one we will use in constructing the diameter for one level up the tree.
So, to sum up:
Recursion first goes all the way down to the tree and returns the longest path in that sub-tree, passing it upwards to its parent, all the way up to the root.
This question already has answers here:
Java Printing a Binary Tree using Level-Order in a Specific Format
(23 answers)
Closed 8 years ago.
PS: This is NOT HOMEWORK. And I didn't understand the other question answer's, otherwise I wouldnt be opening a new one...
I'm trying to print this tree:
3
/ \
7 2
/ \ \
0 9 11
/ \ / \
1 2 6 4
As a level order output:
3
7 2
0 9 11
1 2 6 4
The problem is my code can only print trees like this: 3 7 2 0 9 11 1 2 64, which is the same as the last numbers but without a paragraph or '\n'. I can't seem to find an easy way to do this (preferencially without using foreach). Someone told me I should create a variable: 'level' on the tree that classifies in which level the node is, but how can I even classify the levels?
Can you help me?
public void largura() { //just an auxiliar method to call 'larguras'
larguras(root);
System.out.println();
}
private void larguras(Node t) {
LinkedList<Node> f = new LinkedList<Node>();
Node r;
f.add(t);
while (!f.isEmpty()) {
r=f.remove();
if (r!=root) System.out.print(" ");
System.out.print(r.value);
if (r.left != null) f.add(r.left);
if (r.right != null) f.add(r.right);
}
}
Hmmm... Would something like this work?
//Prints the tree in level order
public void printTree(){
printTree(root);
}
public void printTree(TreeNode tmpRoot){
//If the first node isn't null....continue on
if(tmpRoot != null){
Queue<TreeNode> currentLevel = new LinkedList<TreeNode>(); //Queue that holds the nodes on the current level
Queue<TreeNode> nextLevel = new LinkedList<TreeNode>(); //Queue the stores the nodes for the next level
int treeHeight = height(tmpRoot); //Stores the height of the current tree
int levelTotal = 0; //keeps track of the total levels printed so we don't pass the height and print a billion "null"s
//put the root on the currnt level's queue
currentLevel.add(tmpRoot);
//while there is still another level to print and we haven't gone past the tree's height
while(!currentLevel.isEmpty()&& (levelTotal< treeHeight)){
//Print the next node on the level, add its childen to the next level's queue, and dequeue the node...do this until the current level has been printed
while(!currentLevel.isEmpty()){
//Print the current value
System.out.print(currentLevel.peek().getValue()+" ");
//If there is a left pointer, put the node on the nextLevel's stack. If there is no ponter, add a node with a null value to the next level's stack
tmpRoot = currentLevel.peek().getLeft();
if(tmpRoot != null)
nextLevel.add(tmpRoot);
else
nextLevel.add(new TreeNode(null));
//If there is a right pointer, put the node on the nextLevel's stack. If there is no ponter, add a node with a null value to the next level's stack
tmpRoot = currentLevel.remove().getRight();
if(tmpRoot != null)
nextLevel.add(tmpRoot);
else
nextLevel.add(new TreeNode(null));
}//end while(!currentLevel.isEmpty())
//populate the currentLevel queue with items from the next level
while(!nextLevel.isEmpty()){
currentLevel.add(nextLevel.remove());
}
//Print a blank line to show height
System.out.println("");
//flag that we are working on the next level
levelTotal++;
}//end while(!currentLevel.isEmpty())
}//end if(tmpRoot != null)
}//end method printTree
public int height(){
return height(getRoot());
}
public int height(TreeNode tmpRoot){
if (tmpRoot == null)
return 0;
int leftHeight = height(tmpRoot.getLeft());
int rightHeight = height(tmpRoot.getRight());
if(leftHeight >= rightHeight)
return leftHeight + 1;
else
return rightHeight + 1;
Or perhaps something like this:
public void BFSPrint()
{
Queue<Node> q = new LinkedList<Node>();
q.offer(root);
BFSPrint(q);
}
private void BFSPrint(Queue<Node> q)
{
if(q.isEmpty())
return;
int qLen = q.size(),i=0;
/*limiting it to q size when it is passed,
this will make it print in next lines. if we use iterator instead,
we will again have same output as question, because iterator
will end only q empties*/
while(i<qLen)
{
Node current = q.remove();
System.out.print(current.data+" ");
if(current.left!=null)
q.offer(current.left);
if(current.right!=null)
q.offer(current.right);
i++;
}
System.out.println();
BFSPrint(q);
}
Essentially you are doing something like this:
http://leetcode.com/2010/09/printing-binary-tree-in-level-order.html
The code above will not work for a tree of more than 3 levels that's for you to figure out.
# commenter / -1'er I gave an example so they can play with it. It would appear that this is either homework or a sample exercise and I find playing with the code itself is more helpful to learning. Thats why I gave multiple implementations.