Search if a binary-tree is subtree of another binary-tree - java

I have a serious problem with recurive search of subtree in onether one.
I try this but...
public static boolean containsTree (Node t1, Node t2)
{
if (t2 == null)
return true;
// Empty tree is always a subtree.
else
return subTree(t1, t2);
}
public static boolean subTree (Node t1, Node t2)
{
if (t1 == null)
return false; // Big tree is over.
if (t1.getName().equalsIgnoreCase(t2.getName()))
return matchTree(t1, t2);
return (subTree(t1.getChild(), t2) || subTree(t1.getBrother(), t2));
}
private static boolean matchTree (Node t1, Node t2)
{
if (t1 == null && t2 == null)
return true; // Both trees are empty.
if (t1 == null || t2 == null)
return false; // Big tree empty and subtree still not found.
if (!t1.getName().equalsIgnoreCase(t2.getName()))
return false;
return (matchTree(t1.getChild(), t2.getChild()) && matchTree(
t1.getBrother(), t2.getBrother()));
}
seems to be not correctly formed.
the containsTree function, stop to search when find a node that is different from onether one.
Below, you can find an example of two tree.
1
/ \ 3
/ \ /\
/ \ / \
2 3 7 8
/\ /\
/ \ / \
3 4 5 6
\
3
/\
/ \
7 8
In this case when the function compare the subtree on the right with subtree on the left, it stop to search when find equals parent node but it have different child node.
I need that the function don't stop to search but go throw this point and search for all other child node and their subtree.

say our class is like this:
class Node{
node left, right;
int value;
boolean equals(Node n){
// if one child is null we can skip
if(this.left == null && this.left != null ||
this.left != null && this.left == null ){
return false;
}
if(this.right == null && this.right != null ||
this.right != null && this.right == null ){
return false;
}
//
return (this.value == n.value) &&
( this.left == null || (this.left.equals(n.left)) ) &&
// if this.left == null, n.left is null too and the || will skip the equals()
( this.right == null || (this.right.equals(n.right)) );
// same for right
}
}
this method will recursively check if a tree looks the same as another
so, lets check if its a subtree:
boolean isSubTree(Node other){
return this.equals(other) ||
(other.left != null && this.isSubTree(other.left)) ||
// if left is null, this cant be a subtree
(other.right != null && this.isSubTree(other.right));
// same for right
}
Nothing tested but i think it could be work like this. I skipped constructors and other functions.
(bit overloaded return statements :P )
you should keep some things in your mind: trees are usually used to search for values, and are mostly implemented as binary trees were: left-child < parent < right-child
edit
obviously you should make sure that your tree does not circle :P

Related

Binary tree recursion java

I want to write a function which returns a string of 0s and 1s to signify a path from root Node to specific node p, where 0 means go left, and 1 means go right.
__3__
/ \
4 5
/ \ /
9 2 1
2 should return "01"
public String traverse(TreeNode root, TreeNode p,String s) {
if (root == p) return s;
if (root.left != null) return traverse(root.left,p,s + "0");
if (root.right != null) return traverse(root.right,p,s+ "1");
return "-1";
}
This is my idea of recursive way but it just returns -1 when it gets to a leaf, whereas i want it to continue the recursion. As in, to find 2, it tries 3 -> 4-> 9, but does not continue 4's recursion, but stops at 9. What can I do?
You are returning a special sentinel value, "-1" when you don't find the value you're looking for on a particular branch of the tree.
But you're not checking for this value anywhere in your code - when the value you're looking for isn't on the left branch of the tree, you need to search in the right branch.
So, you need to add a check after searching the left branch of the tree that you didn't get the sentinel value as the result. If you did, you need to continue searching.
public String traverse(TreeNode root, TreeNode p, String s) {
if (root == p) {
return s;
}
if (root.left != null) {
String result = traverse(root.left, p, s + "0");
if (!"-1".equals(result)) {
return result;
}
}
if (root.right != null) {
return traverse(root.right, p, s + "1");
}
return "-1";
}

how can I check if a BST is symmetric in its structure

I'm coding a program and i need to know if a BST is symmetric in its structure
public void traverse (Layer root){
if (root.leftChild != null){
traverse (root.leftChild);
}
if (root.rightChild != null){
traverse (root.rightChild);
}
I have the traverse code but i dont know how to check if it is symmetric
Thanks for the help
I learned how to do this during school, and this is what I did. I learned it from a website I can't remember, but I kept the comments in it.
boolean isMirror(Node node1, Node node2)
{
// if both trees are empty, then they are mirror image
if (node1 == null && node2 == null)
return true;
// For two trees to be mirror images, the following three
// conditions must be true
// 1 - Their root node's key must be same
// 2 - left subtree of left tree and right subtree
// of right tree have to be mirror images
// 3 - right subtree of left tree and left subtree
// of right tree have to be mirror images
if (node1 != null && node2 != null && node1.key == node2.key)
return (isMirror(node1.left, node2.right)
&& isMirror(node1.right, node2.left));
// if neither of the above conditions is true then
// root1 and root2 are mirror images
return false;
}
boolean isSymmetric(Node node)
{
// check if tree is mirror of itself
return isMirror(node, node);
}
public boolean isSymmetric(Layer root) {
return root == null || isSymmetric(root.left, root.right);
}
public boolean isSymmetric(Layer left, Layer right) {
if (left == null && right == null) return true;
return left != null && right != null && left.val == right.val && isSymmetric(left.left, right.right) && isSymmetric(left.right, right.left);
}
I suppose that you mean that tree is symmetric if it is form a "mirror" of itself

check to see if tree has 0 or 2 children

How do I check to see if the entire tree is semi-perfectly has 0 or 2 nodes? Consider the following conditions:
A node with 0 children is semi-perfect.
A node with 1 child is NOT semi-perfect.
A node with 2 children is semi-perfect if
(size-of-larger-child <= size-of-smaller-child * 3)
This is what I have so far:
public static boolean isLeafOrHasTwoChildren(Node t) {
if (t.left == null && t.right == null) {
return true;
}
if (t.left == null || t.right == null) {
return false;
}
// Recurse down the tree
return isLeafOrHasTwoChildren(t.left)
&& isLeafOrHasTwoChildren(t.right);
}
Size computes the number of nodes in the tree.
Let's enumerate our conditions.
You return true if all visited nodes are null.
You return true if all visited nodes are defined.
You return false otherwise.
Let's identify the first condition - isLeaf - as:
boolean isLeaf = t.left == null && t.right == null;
Let's define hasAllChildren as:
boolean hasAllChildren = !(t.left == null || t.right == null);
If we look closely, !(t.left == null || t.right == null) is the same as t.left == null && t.right != null due to DeMorgan's Law. This allows us to express this fairly straightforwardly, and this is likely the piece you're missing.
Now, let's discuss recursive flow. We want to walk down the entire chain of nodes, in a visit-left-right fashion. So, we want to check our conditions before we recurse.
Base case: If we're not a leaf (implying we don't have all children), we return false immediately.
Recursive step: If we're a leaf or we have all children, we continue down the chain.
Let's try to express this.
public static boolean isLeafOrHasTwoChildren(Node t) {
// Trivial case; if we have an undefined node, we've definitely reached a leaf.
if (t == null) {
return true;
}
boolean isLeaf = t.left == null && t.right == null;
boolean hasAllChildren = !(t.left == null || t.right == null);
if(isLeaf || hasAllChildren) {
return isLeafOrHasTwoChildren(t.left) && isLeafOrHasTwoChildren(t.right);
} else {
return false;
}
}

Lowest Common Ancestor in Java

I've found a solution to this problem, in this code,
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if(root == null) return null;
if(root == p || root == q) return root;
TreeNode left = lowestCommonAncestor(root.left, p, q);
TreeNode right = lowestCommonAncestor(root.right, p, q);
return left != null && right != null ? root : left == null ? right : left;
}
I just can't seem to understand the last line. Can someone help me understand how the code works in the last line.
I assume you're aware this makes use of the ternary operator.
It might be easier to understand if you saw it surrounded with parenthesis:
return (left != null && right != null ? root : (left == null ? right : left));
Meaning, this could be rewritten as the following nested if:
if (left != null && right != null) {
return root;
} else {
if (left == null) {
return right;
} else {
return left;
}
}
So let's break it down. You've already checked recursively the left child sub-tree and the right child sub-tree. Now you need to decide which node you're going to return.
If both children exist (left != null && right != null), then the lowest common ancestor of both sub-trees is the current node, meaning the root, which is why you return it.
If however, one of the sub-trees doesn't exist, for instance in the following case when looking at node2 who only has one child:
root
/ \
node1 node2
/ \ \
node3 node4 node5
Then the root cannot be the lowest common ancestor, which means it has to be in one of the sub-trees. Since one of them is null (doesn't exist), then it has to be in the other.
So if left == null then return the lowest common ancestor you've found on the right sub-tree, otherwise the right-subtree doesn't exist (is null) and so return the lowest common ancestor you've found on the left sub-tree.
The ternary operator is used to determine which value is returned. It mighy be a bit clearer if you set braces appropriatly:
return (left != null && right != null) ? root : ((left == null) ? right : left);
Alternatively, you can rewrite the statement to use if's, which might make it a bit clearer:
if (left != null && right != null) {
return root;
} else {
if (left == null) {
return right;
} else {
return left;
}
}

Check if two trees are identical

I've made my own Tree class and I trying to check if two trees are identical. But the problem here is I'm using this call :
Tree myTree = new Tree();
Tree mySecondTree = new Tree();
myTree.isIdentical(myTree, mySecondTree);
It's kind of odd to pass it this way, I want to pass it this way :
myTree.isIdentical(mySecondTree);
isIdentical function :
class Tree<T>{
T data;
Tree left;
Tree right;
Tree(T data){
this.data = data;
}
public boolean isIdentical(Tree t1, Tree t2){
if(t1 == t2)
return true;
if(t1==null || t2==null)
return false;
return (
(t1.data == t2.data) &&
(isIdentical(t1.left, t2.left)) &&
(isIdentical(t1.right, t2.right))
);
}
}
I tried using Stack, but I'm kind of stuck on this
Since you want to execute it this way
myTree.isIdentical(mySecondTree);
You could do this
public boolean isIdentical(Tree t2){
Tree t1 = this;
return isIdentical(t1, t2);
}
private boolean isIdentical(Tree t1, Tree t2){
if(t1 == t2)
return true;
if(t1==null || t2==null)
return false;
return (
(t1.data == t2.data) &&
(isIdentical(t1.left, t2.left)) &&
(isIdentical(t1.right, t2.right))
);
}
Your data-structure allows you to call the modified isIdentical(Tree<T>) method in the left and right child nodes after a few checks. Remember that the parent, right-child and left-child are all different Tree node instances in your code.
public boolean isIdentical(Tree<T> that) {
if (this == that)
return true;
if (that == null)
return false;
//check the equality of the current node's data for both this and that.
if (this.data == that.data || (this.data != null && this.data.equals(that.data))) {
//check the left hand side of the current node for both this and that.
if ((this.left == null && that.left == null
|| this.left != null && this.left.isIdentical(that.left))
//check the right hand side of the current node for both this and that.
&& (this.right == null && that.right == null
|| this.right != null && this.right.isIdentical(that.right))) {
return true;
}
}
return false;
}
You could stay with a recursion and make isIdentical(myTree, Othertree) private. Then wrap it inside a method IsIdentical(otherTree) that calls the method with two arguments suppling this (refrence to the current object) as the first parameter.

Categories