Tree Structure Not Correctly Printing Out - java

I am having trouble with a basic binary search tree that I have created in Java. I am trying to output the tree structure in the console with prepended spaces before a nodes value with respect to how deep the node is.
For some reason my printTree() function is outputting a tree structure that seems slightly backwards. I wouldn't think that (5 0.0) would be indented because it would stay as the root in a basic tree like this.
Below is my function and the output:
Note: c creates the root, s adds a key and value, and xp outputs the tree.
private int k;
private float d;
private Node left, right;
public Node(int k) {
this.k = k;
}
public Node(int k, float d) {
this.k = k;
this.d = d;
}
private int height(Node n) {
if (n == null)
return -1;
return 1 + Math.max(height(n.left), height(n.right));
}
private void printTree(Node n) {
if (n == null)
return;
System.out.println(new String(new char[3 * height(n)]).replace("\0", " ") + "(" + n.k + " " + n.d + ") ");
printTree(n.left);
printTree(n.right);
}
Output:
I'm pretty sure that based on my input that 5 should not be indented at all because it would be root node.
I believe that it should look something like (based on a binary search tree):
(5 0.0)
(4 1.2)
(2 3.5)
(6 7.5)
(87 96.5)
(with the correct amount of prepended spaces of course)
Can anybody explain what I'm doing wrong?

You calculate the number of spaces as 3*height(n). height(n) calculates the maximum path length of the left and the right tree, so the root will always be the furthest to the right.
either calculate the height of a node as the length of the path from the node to the root or precalculate the maximum height and set the number of whitespaces for a node to maxHeight - height(n).

Related

Binary Tree basics

I am following a leet code task which is called Binary tilt. The link to the question is here: https://leetcode.com/problems/binary-tree-tilt/description/
I was stuck on the question so had a look at the solution and I was hoping someone could interpret parts of the below solution for me:
public class Solution {
int result = 0;
public int findTilt(TreeNode root) {
postOrder(root);
return result;
}
private int postOrder(TreeNode root) {
if (root == null) return 0;
int left = postOrder(root.left);
int right = postOrder(root.right);
result += Math.abs(left - right);
return left + right + root.val;
}
}
integers left and right are set to a value every time the recursion happens. What I don’t understand is where this value comes from as in I thought the root.val method would need to be used. Can you explain this in layman terms?
When the method postOrder returns left+right+rootval where is the method returned to? How is it used with the recursive method?
I think what is confusing you is that calculating sum of left and right subtree and calculating tilt for each node is combined in one method. So, I simplified the code that you provided for it to be easier to understand and added comments to it. Though, this way it is much less effective cause you calculate sum for left and right subtree of every node(on each call to calculateTilt), but it is still accepted by leetcode:
public class Solution {
int result = 0; //instance variable to accumulate result(tilt) for all nodes in the tree
public int findTilt(TreeNode root) {
calculateTilt(root);
return result;
}
private void calculateTilt(TreeNode root) {
if (root == null)
return;
int left = findTreeSum(root.left); //find sum of all nodes values of the left subtree
int right = findTreeSum(root.right); //find sum of all nodes values of the right subtree
result += Math.abs(left - right); //add tilt of current node to the result
calculateTilt(root.left); //recursively calculate tilt for the left subtree
calculateTilt(root.right); //recursively calculate tilt for the right subtree
}
//method to find sum of all nodes values for the tree starting at root
private int findTreeSum(TreeNode root){
if (root == null)
return 0;
return findTreeSum(root.left) + findTreeSum(root.right) + root.val;
}
}
Hope this will help!

Maximum Height of a Binary Tree

Hi I came across a code to find the maximum height of a binary tree.
In this code why is there a +1 in the return statement?
public int maxDepth(TreeNode root) {
if (root == null) {
return 0;
}
return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1;
}
If there wasn't, the result would always be 0.
The max height of a binary tree is the max height of the child having a larger max height (that's the Math.max(maxDepth(root.left), maxDepth(root.right)) part) + 1 for the root of the tree.
Consider a tree consisting of a single root node. Then the following return statement would return 1, which is what we expect:
return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1;
return Math.max(0, 0) + 1;
return 1;
As your base case shows, an empty tree would have a height of zero, and you can build up to taller trees' height using induction.

How to count number of nodes in a complete binary tree without visiting each node?

I have the trivial solution to counting the number of nodes in a complete binary tree:
public int countNodes(TreeNode root) {
if (root == null) { return 0; }
return 1 + countNodes(root.left) + countNodes(root.right);
}
I understand this. However, I am aware that it is inefficient as it has to visit each node. I have another solution that I found online:
public int countNodes(TreeNode root) {
if(root==null)
return 0;
int left = getLeftHeight(root)+1;
int right = getRightHeight(root)+1;
if(left==right){
return (2<<(left-1))-1; //having a hard time here
}else{
return countNodes(root.left)+countNodes(root.right)+1;
}
}
public int getLeftHeight(TreeNode n){
if(n==null) return 0;
int height=0;
while(n.left!=null){
height++;
n = n.left;
}
return height;
}
public int getRightHeight(TreeNode n){
if(n==null) return 0;
int height=0;
while(n.right!=null){
height++;
n = n.right;
}
return height;
}
I understand this but I'm not completely sure I understand the condition if (leftHeight == rightHeight). How does this work? Also, could someone please explain the bitwise operation and the reason for why this works? Im not familiar with bitwise operators. Perhaps, if someone could replace that condition with none-bitwise code, and translate whats going on that would be perfect!
The condition (leftHight == rightHight) in a subtree of a tree that we know is a complete tree means that the current subtree is a perfect (full) binary tree. In a perfect binary tree every node has exactly two children except the leaf nodes which have no children.
The bitwise statement (2<<(left-1))-1 is the same as Math.pow(2, left) - 1.
In general powers of 2 can be calculated as below:
2<<0 //equals 2 to the power of 1. 2 is shifted zero bits to the left
2<<1 //equals 2 to the power of 2, 2 is shifted 1 bit to the left
2<<2 // equals 2 to the power of 3, 2 is shifted 2 bits to the left
2<<k // equals 2 to the power of k+1, 2 is shifted k bits to the left
Now if you look at the link above you'll see that the number of nodes in a perfect binary tree of height h is (2**(k+1))-1. That is 2 to the power of (k+1) minus 1.
In the above code left is height+1 notice the plus one in the code. There fore (2<<(left-1))-1 is really calculating the the number nodes in that perfect binary tree.

Finding the Height of a Binary Search Tree in Java using Vertex

I have problems writing this method public int getHeight, where i have to find the height of the binary search tree, using recursion. The reason is that my main class, is made with private comparable mKey and private vertex mLeft, mRight, and mParent, instead of nodes. Would love some help.
public int getHeight(Tree t, int depth)
{
if(t == null){
return depth;
}
else{
return Math.max(getHeight(t.mLeft, depth + 1), getHeight(t.mRight, depth + 1))
}
}
This returns the length of the deepest branch in the tree.
EDIT:
call with getHeight(tree,0)

find longest path of white nodes

This question was asked in an interview:
Tree with black and white nodes is given. Find a longest path of white nodes in the given tree.Is the approach below correct or somebody help with a better approach thanks!
int Longest(node root, int max)
{
if(root==null || root.color == black)
return 0;
if(root.color == white)
{
int curmax =1+ firstlongest(root.child) + secondlongest(root.child);
if(curmax>max)
max = curmax;
return curmax;
}
if(root.color == black)
{
for(all children)
{
int curmax =1+ firstlongest(root.child) + secondlongest(root.child);
}
if(curmax>max)
max =curmax;
return 0;
}
}
int firstlongest(node* child){//will calculate first longest of children and similarly
secondlongest gives second.Finally max will have length of longest path.
Intro:
First remember how to find a longest path in a tree. You take an arbitrary vertex v, find the farthest from it vertex u with bfs, then find the farthest from u vertex t, again with bfs, and (u,t) path will be the longest in the tree. I will not prove it here, you can either google for it or try to prove yourself (it's quite obvious though, if you run it on some examples).
Solution:
Now your problem. We don't need black nodes, so let's throw them away :) The remaining graph will be a forest, i.e. set of trees. Find longest paths for every tree with known algorithm and choose the longest among all.
Complexity:
Described algo will perform one linear pass to remove black nodes, and two linear bfs for each tree in the forest, which are linear to all nodes in graph. Totally: O(n) + O(n+m) + O(n+m) = O(n+m)
Your procedure only seems to compute paths that go down. Assuming all nodes white, it will miss the longest path in this tree:
r
/
a
/ \
b c
/ \
d e
The longest path is dbace.
The code seems incorrect for me. The following section:
if(root.color == black)
{
for(all children)
{
int curmax = max(longest(root.child[i], max));
}
if(curmax>max)
max =curmax;
return 0;
}
will never be executed, because if root.color == black method will return 0 earlier.
Here is how I would do this:
private static int longestWhitePathFromRootLength (Node node)
{
if (node.color == BLACK)
return 0;
else // node.color == WHITE
{
int l = 0;
for (Node n: node.children)
{
l = Math.max (l, longestWhitePathFromRootLength (n));
}
return l + 1;
}
}
public static int longestWhitePathLength (Node node)
{
int l = 0;
for (Node n: node.children)
{
l = Math.max (l, longestWhitePathLength (n));
}
return Math.max (l, longestWhitePathFromRootLength (node));
}

Categories

Resources