Iterative Solution to finding if a tree is balanced - java

So someone posted their solution to this, but I found that it didn't seem to work, I posted this there but I wanted to make it more accessible to others.
The question is in "Cracking the Code Interview" and it is the first tree question, feel free to make other suggestions (or prove me wrong!)

The key here is that it is difficult to keep track of the eventual paths and their heights with one stack.
What I ended up doing is pushing both the left and right child's height on a stack, checking if they are within one of one another, adding one to the max and then pushing that onto the stack after popping the left and right off.
I have commented so I hope it's clear enough
/* Returns true if binary tree with root as root is height-balanced */
boolean isBalanced(Node root) {
if(root == null) return false;
Deque<Integer> heights = new LinkedList<>();
Deque<Node> trail = new LinkedList<>();
trail.push(root);
Node prev = root; //set to root not null to not confuse when root is misisng children
while(!trail.isEmpty()) {
Node curr = trail.peek(); //get the next node to process, peek because we need to maintain trail until we return
//if we just returned from left child
if (curr.left == prev) {
if(curr.right != null) trail.push(curr.right); //if we can go right go
else {
heights.push(-1); //otherwise right height is -1 does not exist and combine heights
if(!combineHeights(heights)) return false;
trail.pop(); //back to parent
}
}
//if we just returned from right child
else if (curr.right == prev) {
if(!combineHeights(heights)) return false;
trail.pop(); //up to parent
}
//this came from a parent, first thing is to visit the left child, or right if no left
else {
if(curr.left != null) trail.push(curr.left);
else {
if (curr.right != null) {
heights.push(-1); //no left so when we combine this node left is 0
trail.push(curr.right); //since we never go left above logic does not go right, so we must here
}
else { //no children set height to 1
heights.push(0);
trail.pop(); //back to parent
}
}
}
prev = curr;
}
return true;
}
//pop both previous heights and make sure they are balanced, if not return false, if so return true and push the greater plus 1
private boolean combineHeights(Deque<Integer> heights) {
int rightHeight = heights.pop();
int leftHeight = heights.pop();
if(Math.abs(leftHeight - rightHeight) > 1) return false;
else heights.push(Math.max(leftHeight, rightHeight) + 1);
return true;
}

So in the end I managed to create an iterative solution which works for all test cases on Leetcode
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public static boolean isBalanced(TreeNode root) {
if (root == null) return true;
Deque<Pair> queue = new LinkedList<>();
queue.offer(new Pair(root, 0));
while (!queue.isEmpty()) {
var curr = queue.poll();
System.out.printf(">>Curr node is %s and curr.lvl is %s", curr.node.val, curr.lvl);
int left = getSubTreeHeight(new Pair(curr.node.left, curr.lvl + 1));
int right = getSubTreeHeight(new Pair(curr.node.right, curr.lvl + 1));
if (Math.abs(left - right) > 1) return false;
if (curr.node.left != null) queue.offer(new Pair(curr.node.left, curr.lvl + 1));
if (curr.node.right != null) queue.offer(new Pair(curr.node.right, curr.lvl + 1));
}
return true;
}
static int getSubTreeHeight(Pair pair) {
if (pair.node == null) {
return pair.lvl -1;
}
Deque<Pair> queue = new LinkedList<>();
queue.offer(pair);
int height = 0;
while (!queue.isEmpty()) {
Pair curr = queue.poll();
System.out.printf("Curr node is %s and curr.lvl is %s", curr.node.val, curr.lvl);
height = curr.lvl;
if (curr.node.left != null) queue.offer(new Pair(curr.node.left, curr.lvl + 1));
if (curr.node.right != null) queue.offer(new Pair(curr.node.right, curr.lvl + 1));
}
return height;
}
public static class Pair {
TreeNode node;
int lvl;
public Pair(TreeNode node, int lvl) {
this.node = node;
this.lvl = lvl;
}
}
}

The original question in the book does not mention the tree being binary. I happen to solve the same question, but coded in Python. So, here is my iterative solution for the problem, for general trees (where the children of a node is stored in a list), in python.
def is_balanced_nonrecursive(self):
stack = [self.root]
levels = [0]
current_min = sys.maxint
current_max = 0
current_level = 0
while len(stack) > 0:
n = stack.pop()
current_level = levels.pop()
for c in n.children:
stack.append(c)
levels.append(current_level + 1)
if len(n.children) == 0:
if current_level < current_min:
current_min = current_level
if current_level > current_max:
current_max = current_level
return current_max - current_min < 2
This is basically a depth first traversal of the tree. We keep a separate stack for the levels (the list levels). If we see any leaf node, we update the current min and current max levels accordingly. The algorithm traverses the whole tree and at the end if max and min levels differ by more than one, then the tree is not balanced.
There are many optimizations possible, like for instance checking whether the difference of min and max is more than one inside the loop, and if that is the case return False immediately.

Some code repetition on this one, but at least it doesn't give me a headache as the recursive ones do:
public boolean isBalanced() {
Queue<TreeNode> queue = new LinkedList<TreeNode>();
int leftLevel = 0;
int rightLevel = 0;
if(this == null) return false;
if(this.left != null)queue.offer(this.left);
while(!queue.isEmpty()) {
int size = queue.size();
for(int i=0; i < size; i++) {
if(queue.peek().left != null) queue.offer(queue.peek().left);
if(queue.peek().right != null) queue.offer(queue.peek().right);
queue.poll();
}
leftLevel++;
}
if(this.right != null) queue.offer(this.right);
while(!queue.isEmpty()) {
int size = queue.size();
for(int i=0; i < size; i++) {
if(queue.peek().left != null) queue.offer(queue.peek().left);
if(queue.peek().right != null) queue.offer(queue.peek().right);
queue.poll();
}
rightLevel++;
}
return Math.abs(leftLevel - rightLevel) < 2;
}

Related

Why is recursion causing the count to return 2 instead of 4?

I am trying to do the Balanced Tree question on Leetcode where you return true only if height of left subtree - height of right subtree <= 1.
Why is the depth of the left subtree returning a 2 when it should return 4? Is there something I am interpreting wrongly? I attached a picture of the tree at the bottom.
Input: [1,2,2,3,3,null,null,4,4,null,null,5,5]
Output: True (because left subtree is returning 2 instead of 4)
Expected Output: False
Print Statements:
left subtree: 2
right subtree: 1
result: 1 (left subtree - right subtree)
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public boolean isBalanced(TreeNode root) {
// 1 2 2 3 3 4 4
//
if (root == null) return true;
System.out.println("left subtree: " + findDepth(root.left,1));
System.out.println("right subtree: " + findDepth(root.right,1));
System.out.println("result: " + Math.abs(findDepth(root.left,1) - findDepth(root.right, 1)));
if ( Math.abs(findDepth(root.left,1) - findDepth(root.right, 1)) <= 1) return true;
return false;
}
public static int findDepth(TreeNode root, int count) {
if (root == null) return count;
if (root.left != null) {
count++;
findDepth(root.left, count);
}
if(root.left == null && root.right == null) return count;
return count;
}
}
Image of Binary Tree
The reason why you get 2 is because when you recurse, the recursive call is not incrementing the count variable that you pass in. Instead, it increments its own copy of it. Java is pass by value.
if (root.left != null) {
count++;
// the call below will not change "count" at all
findDepth(root.left, count);
// it will only change its own copy
}
Therefore, the recursive call practically does nothing. You are not even using its return value. Its return value is actually the modified copy of count that you want count to be set to, so to fix this, set count to the return value of findDepth:
value = findDepth(root.left, count);
This will give you the expected 4, but your findDepth should also check the right subtree, and can be improved in other ways. For example, you don't actually need a count argument.
public static int findDepth(TreeNode root) {
if (root == null) return 0;
return 1 + Math.max(findDepth(root.left), findDepth(root.right));
}
Because you are only counting the depth of the left side of the tree in findDepth methof by applying condition
if (root.left != null) {
count++;
findDepth(root.left, count);
}
You can modify your method like this
public static int findDepth(TreeNode root, int count) {
if (root == null) return count;
return Math.max(findDepth(root.left, count+1),findDepth(root.right, count+1));
}

How to create a binary search tree that includes all numbers from 1 to n

Im trying to create a Binary search tree that includes all numbers from 1 to n. an example would be from 1 to 5 would be something like
root: 3
root.left: 2
root.left.left = 1
root.right = 4
root.right.right = 5
This tree happens to be not very balanced, but I would prefer a method that produces as balanced of a tree as possible.
I am trying to create my own data structure for this, so I basically just wrote a Node class:
private class BinaryNode{
int data;
BinaryNode left;
BinaryNode right;
BinaryNode parent;
}
And I planned on having that inside another class, which represents the tree itself. I am stuck finding a good way determine the left/right values appropriately to build the tree, any help is appreciated!
The data on the root node would be (n+1)/2; if you've got a subtree representing the range [i..j], the root of that subtree is (i+j)/2 (using integer arithmetic).
You can build the tree recursively using that fact:
static BinaryNode build(int i, int j) {
if (i > j) return null;
int mid = (i + j) / 2; // Assumes i >= 0.
BinaryNode node = new BinaryNode();
node.data = mid;
node.left = build(i, mid - 1);
if (node.left != null) node.left.parent = node;
node.right = build(mid + 1, j);
if (node.right != null) node.right.parent = node;
return node;
}
Then start the recursive call:
BinaryNode node = build(1, n);
It must be pointed out, however, that such a binary search tree (storing contiguous integers from 1 to n) is useless: you may as well simply use an array, and "search" it using an array index.
public void insert(int id){
Node newNode = new Node(id);
if(root==null){
root = newNode;
return;
}
Node current = root;
Node parent = null;
while(true){
parent = current;
if(id<current.data){
current = current.left;
if(current==null){
parent.left = newNode;
newNode.parent = parent;
return;
}
}else{
current = current.right;
if(current==null){
parent.right = newNode;
newNode.parent = parent;
return;
}
}
}
}
Without recursion insertion of 1 to n numbers.
public static void main(String arg[]){
Solution2 s = new Solution2();
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
for(int i = 1;i <= n;i++){
s.insert(i);
}
}

Binary tree - find position in inorder traversal

I have a binary search tree where i have to implement a method called
int valueAtPosition(int x)
The problem is, that i need the position in an in order traversal.
To find the in order traversal i have this the following code, but i don't know how i count the recursive calls, to get the right position.
public void inOrderTraverseTree(Node root){
if(root != null){
inOrderTraverseTree(root.leftChild);
System.out.println(root);
inOrderTraverseTree(root.rightChild);
}
}
I think the other solutions are O(n). All you need for this is a count of the children for each node for O(log n).
When you insert a node, for each node you traverse you increase the counter on the traversed node by one.
You need to maintain these counters when deleting, rebalancing, etc which normally isn't difficult.
With this you can get the position of the node when inserted, find the position of a node by value or find a node by position.
To find a node by position is the same kind of binary traversal as for finding by value. If you want the item at position 1000 then you start at the root. No root, not item at that position. Then you look at the left child (you can do it in the other order too and switch ascending/descending), on the left if the left child exists the number of children on the left is 0 plus the count of the children on the left node. Let say in this scenario that the left exists and has 500 children. Then you know 1000 can't be left because there aren't enough items on the left, so it must be right. You can repeat this also checking for bounds all the way down.
For simple O(n) in order traversal if you have a global counter you just increase it only after traversing the left. That should do the same as a depth first search. No need for decreasing and increasing counters or pushing and popping on a stack. You can also have your functions return a count.
public int inOrderTraverseTree(Node root){
if(root == null)
return 0;
int count = inOrderTraverseTree(root.leftChild);
count++;
count += inOrderTraverseTree(root.rightChild);
return count;
}
This approach only becomes annoying if you want to return the node as well.
You can of course replace a recursive function with your own stack but this is a rarely needed performance optimisation and you'll be far better off with the O(log n) solution if you need performance than an optimised custom stack based solution.
You can also use a counter in the recursive approach. However, you can't simply pass an int counter argument - you need all calls to see the "same" counter, so you will have to wrap it in a class (or, as in this case, an inner class):
public static class Counter {
private int value;
public Counter(int initialValue) { value = initialValue; }
public boolean decrement() { value--; return value == 0; }
public boolean expired() { return value <= 0; }
}
public Node inOrderTraverseTree(Node root, Counter counter){
if (root != null && ! counter.expired()) {
Node left = inOrderTraverseTree(root.leftChild, counter);
if (left != null) {
return left;
} else if (counter.decrement()) {
return root;
} else {
return inOrderTraverseTree(root.rightChild, counter);
}
} else {
return null;
}
}
To find the 9th node in-order (using 1-based indexing), you would call this as
Node the9th = inOrderTraverseTree(root, new Counter(9));
If there is no 9th node, it would return null. If you want to use 0-based indexing instead, change { value--; return value == 0; } to { return value-- == 0; }
The iterative in-order traversal approach makes this pretty easy. Increment a counter whenever a node is popped from the stack. When the counter is equal to x, return the value of the node.
Integer valueAtPosition(int x, Node root) {
int count = 0;
List<Node> stack = new ArrayList<>();
Node node = root;
while (!stack.isEmpty() || node != null) {
if (node != null) {
stack.add(node);
node = node.leftChild;
} else {
node = stack.pop();
if (count == x) {
return node.value;
}
count++;
node = node.rightChild;
}
}
return null;
}
Recursive version requires passing a mutable wrapper for a counter like so:
public class Counter {
int count = 0;
}
public void inOrderTraverseTree(Node root, int index, Counter counter){
if(root == null || counter.count > index) {
return;
}
inOrderTraverseTree(root.leftChild);
if (counter.count == index) {
System.out.println(root);
}
counter.count = counter.count + 1;
inOrderTraverseTree(root.rightChild);
}
Following is recursive in-order traversal approach: (in c++)
bool valueAtPositionUtil(struct treeNode *root, int &currIndex, int i, int &value) {
if(root != NULL) {
if(valueAtPositionUtil(root->left, currIndex, i, value)) {
return true;
}
if(currIndex == i) {
value = root->data;
return true;
}
currIndex++;
if(valueAtPositionUtil(root->right, currIndex, i, value)) {
return true;
}
}
return false;
}
int ValueAtPosition(int i, struct treeNode *root) {
int value = 0;
int currIndex = 0;
if(valueAtPositionUtil(root, currIndex, i, value)) {
return value;
}
//index out of bound
// you can return according your problem
return -1;
}

Binary Tree Max sum level - Better Design?

I have written a code for finding level in Binary Tree having max sum of elements. I have a few Questions.
Is it a good design ? - I have used 2 queues but the total num of elements both queues store will be less than n. SO I think it should be Ok.
Can there be a better design?
public class MaxSumLevel {
public static int findLevel(BinaryTreeNode root) {
Queue mainQ = new Queue();
Queue tempQ = new Queue();
int maxlevel = 0;
int maxVal = 0;
int tempSum = 0;
int tempLevel = 0;
if (root != null) {
mainQ.enqueue(root);
maxlevel = 1;
tempLevel = 1;
maxVal = root.getData();
}
while ( !mainQ.isEmpty()) {
BinaryTreeNode head = (BinaryTreeNode) mainQ.dequeue();
BinaryTreeNode left = head.getLeft();
BinaryTreeNode right = head.getRight();
if (left != null) {
tempQ.enqueue(left);
tempSum = tempSum + left.getData();
}
if (right != null) {
tempQ.enqueue(right);
tempSum = tempSum + right.getData();
}
if (mainQ.isEmpty()) {
mainQ = tempQ;
tempQ = new Queue();
tempLevel ++;
if (tempSum > maxVal) {
maxVal = tempSum;
maxlevel = tempLevel;
tempSum = 0;
}
}
}
return maxlevel;
}
}
I like recursion (note, untested code):
public static int maxLevel(BinaryTreeNode tree) {
ArrayList<Integer> levels = new ArrayList<Integer>();
findLevels(tree, 0, levels);
// now just return the index in levels with the maximal value.
// bearing in mind that levels could be empty.
}
private static void findLevels(BinaryTreeNode tree, int level,
ArrayList<Integer> levels) {
if (tree == null) {
return;
}
if (levels.length <= level) {
levels.add(0);
}
levels.set(level, levels.get(level) + tree.getData());
findLevels(tree.getLeft(), level+1, levels);
findLevels(tree.getRight(), level+1, levels);
}
If I was feeling really mean to the garbage collector, I'd make findLevels return a list of (level, value) pairs and sum over those. That makes a lot more sense in co-routiney sort of languages, though, it'd be weird in java.
Obviously you can take the strategy in the recursive function and do it with an explicit stack of nodes to be processed. The key difference between my way and yours is that mine takes memory proportional to the height of the tree; yours takes memory proportional to its width.
Looking at your code, it seems pretty reasonable for the approach. I'd rename tempLevel to currentLevel, and I'd be inclined to pull the inner loop out into a function sumLevel that takes a queue and returns an int and a queue (except actually the queue would be an argument, because you can only return one value, grrr). But it seems okay as is.
It depends on how many nodes your trees have and how deep they are. Since you're performing breadth first search, your queues will take O(n) memory space, which is OK for most applications.
The following solution has O(l) space complexity and and O(n) time complexity (l is the depth of a tree and n number of its vertices):
public List<Integer> levelsSum(BinaryTreeNode tree) {
List<Integer> sums = new ArrayList<Integer>()
levelsSum(tree, sums, 0);
return sums;
}
protected void levelsSum(BinaryTreeNode tree, List<Integer> levelSums, int level) {
if (tree == null)
return;
// add new element into the list if needed
if (level.size() <= level)
levelSums.add(Integer.valueOf(0));
// add this node's value to the appropriate level
levelSums.set(level, levelSums.get(level) + tree.getData());
// process subtrees
levelSum(tree.getLeft(), levelSums, level + 1);
levelSum(tree.getRight(), levelSums, level + 1);
}
Now just call levelsSum on a tree and scan the returned list to find the maximum value.
Are You sure that elements will all be non-negative?
I would make it callable like new MaxSumLevel(root).getLevel(). Otherwise, what will You when You have to sometimes return maxSum ?
I would structure this as 2 nested loops:
while(!mainQ.isEmpty()){
while(!mainQ.isEmpty()){
BinaryTreeNode head = (BinaryTreeNode) mainQ.dequeue();
BinaryTreeNode left = head.getLeft();
BinaryTreeNode right = head.getRight();
if (left != null) {
tempQ.enqueue(left);
tempSum = tempSum + left.getData();
}
if (right != null) {
tempQ.enqueue(right);
tempSum = tempSum + right.getData();
}
}
mainQ = tempQ;
tempQ = new Queue();
tempLevel ++;
if (tempSum > maxVal) {
maxVal = tempSum;
maxlevel = tempLevel;
tempSum = 0;
}
}
This recursive approach works for me:
public int findMaxSumRootLeaf(TreeNode node,int currSum) {
if(node == null)
return 0;
return Math.max(findMaxSumRootLeaf(node.leftChild,currSum)+node.data, findMaxSumRootLeaf(node.rightChild,currSum)+node.data);
}
You can represent end of a level using null in the queue and calculating the maximum sum for each level.
public int maxLevelSum(BinaryTreeNode root) {
if (root == null) //if empty tree
return 0;
else {
int current_sum = 0;
int max_sum = 0;
Queue<BinaryTreeNode> queue = new LinkedList<BinaryTreeNode>(); //initialize a queue
queue.offer(root); //add root in queue
queue.offer(null); // null in queue represent end of a level
while (!queue.isEmpty()) {
BinaryTreeNode temp = queue.poll();
if (temp != null) {
if (temp.getLeft() != null) //if left is not null
queue.offer(temp.getLeft());
if (temp.getRight() != null)
queue.offer(temp.getRight()); //if right is not null
current_sum = current_sum + temp.getData(); //add to level current level sum
} else { // we reached end of a level
if (current_sum > max_sum) //check if cuurent level sum is greater than max
max_sum = current_sum;
current_sum = 0; //make current_sum=0 for new level
if (!queue.isEmpty())
queue.offer(null); //completion of a level
}
}
return max_sum; //return the max sum
}
}

Using a recursive method to find the smallest element in a subtree given the root: what am I doing wrong here?

So I have a homework question where I'm supposed to use a recursive method to "find the minimum element within a subtree rooted at the specified node"
And then I'm given this as my starting point:
public TreeNode
{
int data;
TreeNode left;
TreeNode right;
}
and
/**
Finds the minimum value for the subtree that is
rooted at a given node
#param n The root of the subtree
#return The minimum value
PRECONDITION: n is not null.
*/
int min(TreeNode n)
{
// COMPLETE THE BODY OF THIS METHOD
}
Now, I've got a very basic driver program written to insert nodes into the tree and I've written my recursive method, but it seems to be counting up instead of down, here's my method:
int min(TreeNode n){
if(n.left != null) {
n = n.left;
min(n);
System.out.println("N is now " + n.value);
}
return n.value;
}
Output of my code:
Building tree with rootvalue 25
=================================
Inserted 11 to left of node 25
Inserted 15 to right of node 11
Inserted 16 to right of node 15
Inserted 23 to right of node 16
Inserted 79 to right of node 25
Inserted 5 to left of node 11
Inserted 4 to left of node 5
Inserted 2 to left of node 4
Root is 25
N is now 2
N is now 4
N is now 5
N is now 11
The minimum integer in the given nodes subtree is: 11
Can someone please explain to me why this doesn't work?
Note: this is all assuming you're in a Binary Search Tree, so returning the minimum element means returning the left-most element.
This means your recursive call is quite simple:
min(node):
if this node has a left node:
return min(node.left)
if this node does not have a left node:
return this node's value
The logic is that if we don't have another left node then we are the left-most node, so we are the minimum value.
Now, in Java:
int min(TreeNode n){
if (n.left == null)
return n.value;
return min(n.left); // n.left cannot be null here
}
Now to explain your results, consider how this method works. It calls the method on the next node (min(n.left)) before continuing. In your case you had a println after this recursive call. Therefore the println inside the recursive call went first. So your prints started at the bottom of the tree and worked their way back up. This explains the "reverse order" printing.
Your method then returned 11 as your result because (as another answer has explained) your n = n.left didn't affect any of your recursive sub-calls, only the one in the current function call. This means you returned the left node of the root, rather than the furthest left child.
I hope this makes sense. If you need clarification on anything leave a comment or something. Recursion can be quite tricky to get your head around at first.
The issue is that Java is call-by-value, not by reference -- although references are passed by value. But what that really means in this case is that the call to min(n) does not change what the variable n refers to -- it doesn't do anything at all. What you should probably be doing is return min(n).
public static void main(String[] args) throws IOException, NoSuchMethodException, InitializationError {
Logger.getRootLogger().addAppender(new ConsoleAppender(new SimpleLayout(), "System.out"));
Logger.getRootLogger().setLevel(Level.ALL);
TreeNode n1 = new TreeNode();
TreeNode n2 = new TreeNode();
TreeNode n3 = new TreeNode();
TreeNode n4 = new TreeNode();
TreeNode n5 = new TreeNode();
TreeNode n6 = new TreeNode();
n1.data = 110;
n1.left = n2;
n1.right = n3;
n2.data = 15;
n2.left = n4;
n2.right = null;
n3.data = 3;
n3.left = null;
n3.right = null;
n4.data = 4;
n4.left = null;
n4.right = n5;
n5.data = 12;
n5.left = n6;
n5.right = null;
n6.data = 19;
n6.left = null;
n6.right = null;
System.out.print("min=" + min(n1));
}
static public class TreeNode {
int data;
TreeNode left;
TreeNode right;
}
static int min(TreeNode n) {
return min(n, n.data);
}
static int min(TreeNode n, int min) {
System.out.println("N is now " + n.data);
int currentMin = min;
if (n.left != null && n.right != null) {
final int left = min(n.left);
final int right = min(n.right);
if (left < right) {
currentMin = left;
} else {
currentMin = right;
}
} else if (n.left != null) {
currentMin = min(n.left);
} else if (n.right != null) {
currentMin = min(n.right);
}
if (currentMin < min) {
return currentMin;
} else {
return min;
}
}
OUTPUT is:
N is now 110
N is now 15
N is now 4
N is now 12
N is now 19
N is now 3
min=3
You need to use some tree traversal algoritm, for checking every node of the tree. Also you need to store current finded minimum. Pass this minimum into recursive function. It is calling "accumulator".
The last statement in your method implementation returns the node n's value. As n starts with the root and is replaced by its left child (if exists) you always get the value of the root's left child.
The following code should do it:
int min(final Tree n){
int result;
if(n == null){
result = Integer.MAX_VALUE;
} else {
result = n.value;
final int leftResult = min(n.left);
if(leftResult < result){
result = leftResult;
}
final int rightResult = min(n.right);
if(rightResult < result){
result = rightResult;
}
}
return result;
}
Or you could use the Visitor pattern (you would need to make your tree Iterable then and pass the values to the Visitor one-by-one):
interface TreeVisitor {
void accept(int value);
}
class MinTreeVisistor implements TreeVisitor {
int min = Integer.MAX_VALUE;
#Override
public void accept(int value) {
if(value < this.min) {
this.min = value;
}
}
}

Categories

Resources