Find numbers of nodes between root and give node - java

So in a given binary tree (node binary search tree), initially I want to find the number of nodes between two nodes "p" and "q". I first find the lowest common ancestor between these two nodes, say, "ancestor". Then I calculate the number of nodes between "ancestor" and "p" and number of nodes between "ancestor" and "q" separately and add them at last.
I tried recursive way to get number of nodes between "ancestor" and "p" or "q" but failed. Not a fan of recursive.
public static int NodeToNodePath(BinaryTree root, BinaryTree node, int length){
if(root == null && node == null)
return 0;
if(root == null || node == null)
return 0;
if(root.rootElement == node.rootElement){
return length;
}
int sum = NodeToNodePath(root.left, node, length + 1);
if(sum != 0)
return sum;
sum = NodeToNodePath(root.right, node, sum);
return sum;
}
But in this way, the result from root to left mode is correct but can't find node on the other size.
Any help?
Thanks!

I figure out how to solve the problem. By recursion. This may not apply to my origin problem
"find node number between two given nodes" but it does return number of nodes between root and a given node.
Code is posted below.
public static int NodeToNodePath(BinaryTree root,
BinaryTree node, int length) {
if(root == null)
return 0;
if(root.rootElement == node.rootElement){
length += 1;
return length;
}
int left = NodeToNodePath(root.left, node, length);
if(left != 0){
return left + 1;
}
int right = NodeToNodePath(root.right, node, length);
if(right != 0){
return right + 1;
}
return 0;
}
Also, I found a post on GeekForGeeks talking specifically about my origin problem, it's called "Find distance between two given keys of a Binary Tree" the address is:
http://www.geeksforgeeks.org/find-distance-two-given-nodes/
Thanks everyone!

Related

Counting matching nodes on a tree

I am trying this problem on Practice-It, but have been having trouble with it for quite a while.
Write a method matches that returns a count of the number of nodes in one tree that match nodes in another tree. A match is defined as a pair of nodes that are in the same position in the two trees relative to their overall root and that store the same data.
So far, I've tried the following below, but I don't quite get the count I want, and I'm not quite sure why.
public int matches(IntTree t2)
{
return match(overallRoot, t2.overallRoot);
}
public int match(IntTreeNode tree1, IntTreeNode tree2)
{
if(tree1 == null && tree2 == null)
return 1;
if(tree1 == null || tree2 == null)
return 0;
if(tree1.data == tree2.data)
return 1;
int left = match(tree1.left, tree2.left);
int right = match(tree1.right, tree2.right);
return left + right;
}
Any help would really be appreciated!
You're stopping your search if the current node matches. If it's different, you check left and right, but on a match you return one.
You are very close to the solution, you have to consider:
if one of the nodes is null you can stop the visit for the subtrees and return 0
if the data for the two roots are different the count is 0 otherwise is 1 and after you can calculate the count for the two subtrees adding to the count for the two roots.
Below my suggestions as code:
public int match(IntTreeNode tree1, IntTreeNode tree2) {
if(tree1 == null || tree2 == null) { return 0; }
int count = tree1.data == tree2.data ? 1 : 0;
int left = match(tree1.left, tree2.left);
int right = match(tree1.right, tree2.right);
return count + left + right;
}
Full answer for the practice it one:
int matches(IntTree tree2) {
return matches(tree2.overallRoot, this.overallRoot);
}
int matches(IntTreeNode tree1, IntTreeNode node2)
{
int left=0, right=0, count =0;
if(tree1 == null && this != null || this == null && tree1 != null) { return 0; }
count = tree1.data == node2.data ? 1 : 0;
if(tree1.left != null && node2.left !=null){
left = matches(tree1.left, node2.left);}
if(tree1.right != null && node2.right !=null){
right = matches(tree1.right, node2.right);}
return count + left + right;
}

AVL tree Height Method StackOverFlow Erroe

I am trying to implement AVL tree.I'm having stackOverFlow on height method. I tried with small number of inputs it works. However, When i tried with large scale of input, it crush. Here is my code.
private int height(Node<T> node){
if(!isEmpty() && node != null){
if(isleaf(node))
return 1;
else{
int p = height(node.left);
int q = height(node.right);
if(p > q)
return p + 1;
else
return q + 1;
}
}
return 0;
}
This can happen if your tree has cyclic references. Check tree construction. To debug - assign unique values and print while traversing the nodes.

Min depth of a binary tree using BFT?

I'm trying to figure out the minimum depth to a leaf node using breadth first search. I have the following basic structure
public int BFS(Node root){
if (root == null) return 0;
Queue<Node> q = new LinkedList<Node>();
int min = 1;
q.clear(); // I saw this in a queue example, unsure if needed
q.add(root);
while (! q.isEmpty()){
Node n = q.remove();
if (n.left != null) q.add(n.left);
if (n.right != null) q.add(n.right);
}
}
I'm not sure where to update the min height counter. I had thought about placing it inside the if statements as temp loop variables l & r where I would set them to 1 if the left or right is not null, 0 else. Then add the min of these 2 to the min height but this only works if I'm at one level above the leafs.
The idea should be something like:
First node added to the queue should have distance = 1.
For new nodes added to the queue: distance = actual node distance + 1
When you find a leaf, you return actual node distance. END.
In pseudocode:
root.depth := 1
q := create queue
q.add(root)
while q is not empty
Node n := q.dequeue()
if (n is leaf) then
return n.depth
if (n.left is not null) then
n.left.depth := n.depth + 1
q.add(n.left)
if (n.right is not null) then
n.right.depth := n.depth + 1
q.add(n.right)
return 0
You could use a queue of pairs (node, depth). Since the search is BFT, the first leaf contains the minimum depth.
Based on your code, the algorithm would be something like that (pseudo java code):
public int BFS(Node root)
{
if (root == null)
return 0;
Queue<Pair<Node,int>> q = new LinkedList<Pair<Node,int>>();
q.add(new Pair(root, 0));
while (! q.isEmpty()) {
Pair p = q.remove();
Node n = p.getFirst();
if (n.left == null && n.right == null) // is this a leaf?
return p.getSecond(); // yes! ==> p.getSecond() is its min depth
if (n.left != null)
q.add(new Pair(n.left, p.getSecond() + 1));
if (n.right != null)
q.add(new Pair(n.right, p.getSecond() + 1));
}
}
Of course, you need the Pair class, but I leave to you these details
Generally in BFS, your nodes have a distance field. the roots distance is zero, then whenever you add a new node to the queue, you set its distance to n.distance+1

Binary search tree Recursively return to root

I need to create a method in java that recursively determines the distance from any given node back to the root. The method returns an integer that shows how many nodes away the specific node is from the root. The node class is given below
Public class Node
{
int data;
node left;
node right;
}
No global variables or attributes allowed, and I cannot modify the node class. I've looked it up and each solution tells me to modify the node class to include a node pointer for a parent node. Any help would be appreciated, thanks!
If you have parent stored in each node, search would require O(log N) operations (in case of balanced tree)--you just walk through parents and count steps until parent == null which means root node.
But without parent field, you need to recursively traverse the whole tree starting from the root, looking for a given node. It requires O(N) operations:
/** Returns the distance between "n" and "current" plus "step"
/* or -1 if "n" not found */
int distance(Node n, Node current, int step) {
int res = -1;
if (n == current) // node found
return step;
if (current.left == null && current.right == null) // leaf node
return -1;
if (current.left != null) // search in left subtree
res = distance(n, current.left, step + 1);
if (res > 0)
return res;
if (current.right != null) // search in right subtree
res = distance(n, current.right, step + 1);
return res;
}
//....
Node root;
Node given;
int dist = distance(given, root, 0); // distance between "root" and "given"

Removing nodes between two given positions from singly linked list?

I am teaching myself data structures and following to Java books on this subject. Currently I am learning Linked List implementation. I have been struggling with how to write a method which takes "startPos" and "endPos" and simply removes the nodes accordingly. I am validating "startPos", and "endPos" in order to catch invalid position input. I have Googled for direction but have not come across any online example that can help me get going with this logic. I would highly appreciate any guidance with this please. Thank you.
class Node{
public Object data;
public Node next;
}
Delete Nodes Method
public void deleteNodes( int startPos, int endPos ){
Node node = _nHead;
int counter = 0;
if( startPos < 1 || startPos > getSize() )
return;
if( endPos < 1 || endPos > getSize() )
return;
while( node != null){
node = node.next;
++counter;
}
}
GET SIZE
public int getSize(){
int counter = 0;
for( Node node = _nHead; node != null; node = node.next )
++counter;
return counter;
}
To remove all nodes between two nodes on a singly linked list is not super hard.
You need two placeholders. You move through the linked list until you find your start node, and set one of the placeholders equal to it. You then move your second placeholder through the remainder of the linked list until you find your second node. Set your first node's -> next parameter equal to the second node, and you've effectively removed everything in between.
For proper cleanup, you should keep track of the node that was next after the first node and free all nodes that were removed from memory, but this is more critical in C than Java.
For a doubly-linked list the method is similar, except you also have to set the second node's previous to the first node.
As an example:
public void deleteNodes( int startPos, int endPos ){
Node node = _nHead;
Node start;
Node end;
int counter = 0;
if( startPos < 1 || startPos > getSize() )
return;
if( endPos < 1 || endPos > getSize() )
return;
if (endPos < startPos)
{
int placeholder = startPos;
startPos = endPos;
endPos = placeholder; // switches end and start if start is greater than end
}
if (endPos == startPos)
return; // if they are equal we aren't deleting anything;
while( node != null)
{
if (counter == startPos)
start = node;
if (counter == endPos)
end = node;
node = node.next;
counter++;
}
if (start != NULL && end != NULL)
{
start.next = end;
}
}
You would simply have to set the next pointer of the node at the start of the removal range to the node at the end of the removal range. Since there would be no references to the nodes in the delete range, Java's garbage collection should clear them up.

Categories