another easy one but I can't seem to get it. I need to write a method that compares the structures of two binary trees and returns weather they are the same or not. The data and data types are not important only the structures. Here are some examples:
Here is the code I have so far. I think it is really close.
public boolean sameStructure(OrderedSet<E> other) {
if (other.size() != size)
return false;
return sameStructureHelp(other, root, other.root);
}
private boolean sameStructureHelp(OrderedSet<E> other, TreeNode ref,
TreeNode otherRef) {
if (otherRef == null && ref != null)
return false;
if (otherRef != null && ref == null)
return false;
sameStructureHelp(other, ref.left, otherRef.left);
sameStructureHelp(other, ref.right, otherRef.right);
return true;
}
What you pasted is mostly right, only missing a critical piece: instead of just checking the left and right subtrees, you should return their and value, which would mean if the trees rooted in the current nodes satisfies the condition for being the same stucture.
Thanks #Ziyao Wei
Here is the code which solved the problem:
public boolean sameStructure(OrderedSet<E> other) {
if (other.size() != size)
return false;
return sameStructureHelp(other, root, other.root);
}
private boolean sameStructureHelp(OrderedSet<E> other, TreeNode ref,
TreeNode otherRef) {
if (otherRef == null && ref != null)
return false;
if (otherRef != null && ref == null)
return false;
if (otherRef == null && ref == null)
return true;
return sameStructureHelp(other, ref.left, otherRef.left)
&& sameStructureHelp(other, ref.right, otherRef.right);
}
Related
I'm creating a binary search tree project, and one of the questions is to create 2 trees and check if they're equal or not. When I implement the method, I keep getting
firstTree and secondTree are equal. Here's the relevant code:
BstTest2 firstTree = new BstTest2();
firstTree.addNode(50, "Francisco Domingo Carlos Andres Sebastián d'Anconia");
firstTree.addNode(25, "John Galt");
firstTree.addNode(15, "Hugh Akston");
firstTree.addNode(30, "Ragnar Danneskjöld");
firstTree.addNode(85, "Hank Reardan"); //implementing add method
BstTest2 secondTree = new BstTest2();
secondTree.addNode(50, "Francisco Domingo Carlos Andres Sebastián d'Anconia");
secondTree.addNode(25, "John Galt");
secondTree.addNode(15, "Hugh Akston");
secondTree.addNode(30, "Ragnar Danneskjöld");
secondTree.addNode(75, "Midas Mulligan");
secondTree.addNode(85, "Hank Reardan");
if(firstTree.isEqual(secondTree))
{
System.out.println("firstTree and secondTree are equal");
}
else
{
System.out.println("firstTree and secondTree are not equal");
}
isEqual and check methods for comparing the trees
public boolean isEqual(BstTest2 tree1)
{
return check(this.rootNode, tree1.rootNode);
}
public boolean check(Node node1, Node node2)
{
if((node1 == null) && (node2 == null))
{
return true;
}
else if((node1 == null) || node2 != null)
{
return false;
}
else if((node1 != null) || node2 == null)
{
return false;
}
else
{
return check(node1.leftChild, node2.leftChild) && check(node1.rightChild, node2.rightChild);
}
}
What did I do wrong in my isEqual() and check() methods that I keep getting " firstTree and secondTree are equal" when the trees are not equal?
You forget to check if the value of node1 and node2 are the same.
If they are not the same, it means these two trees are not same.
If they are the same, we keep on checking if their left and right child are the same.
public boolean check(Node node1, Node node2)
{
if((node1 == null) && (node2 == null))
{
return true;
}
// If only one node is null, it means these two trees are not the same
// These two nodes here couldn't both be null because we check this condition earlier.
if(node1 == null || node2 == null)
{
return false;
}
// Check if the value of node1 and node2 are the same
if(node1.val != node2.val)
{
return false;
}
return check(node1.leftChild, node2.leftChild) && check(node1.rightChild, node2.rightChild);
}
I am trying to write a method that will return true if a binary tree is full (each node has 2 child nodes or none) and false otherwise. This is working some of the time but not all. Any suggestions about where I am going wrong?
public static void testNum4()
{
System.out.println("How many nodes do you want in your tree?");
int num=sc.nextInt();
//TreeNode<Integer> root = TreeUtil.createBalancedNumberTree(num); Use to test for a balanced tree
TreeNode<Integer> root = TreeUtil.createIntegerTree(num);
TreeUtil.displayTreeInWindow(root);
System.out.println(isFull(root));
TreeUtil.displayTreeInWindow (root);
}
public static boolean isFull(TreeNode<Integer> root) {
// pre: root of tree, 0 or more nodes
// post: returns true if the input tree is a full tree; false otherwise
if (root!=null) {
if ((root.getLeft() != null && root.getRight() != null) || (root.getRight() == null && root.getLeft() == null))
{
return true;
}
else if (root.getLeft()!=null)
{
isFull(root.getLeft());
}
else if (root.getRight()!=null)
{
isFull(root.getRight());
}
else
return false;
}
return false;
}
Definition: a binary tree T is full if each node is either a leaf or possesses exactly two child nodes.
public static boolean isFull(TreeNode<Integer> root)
// pre: root of tree, 0 or more nodes
// post: returns true if the input tree is a full tree; false otherwise
{
if (root!=null)
{
if(root.getRight() == null && root.getLeft() == null)
{
return true;
}
if ((root.getRight() != null && root.getLeft() != null))
{
return isFull(root.getLeft())&&isFull(root.getLeft());
}
}
return false;
}
Try to add return to each statement.
else if (root.getLeft()!=null && root.getRight()!=null)
{
return isFull(root.getLeft()) && isFull(root.getRight());
}
Also, if the root node is null, then your tree is full. So the last return should be return true;
The problem is the else if and lack of return statements. Also no need to checking for null so much, and use of a method makes it more readable.
public static boolean isFull(TreeNode<Integer> node) {
if (node == null) return false;
if (isLeaf(node)) return true;
return isFull(node.getLeft()) && isFull(node.getRight());
}
public static boolean isLeaf(TreeNode<Integer> node) {
return node.getRight() == null && node.getLeft() == null;
}
You are not fully traversing the tree. Use recursion to hit all the nodes. Check the root node. If there are no children, return true. If there are children, make sure there are two, and then check each of them recursively.
I think that the if statements should be as follows:
if (root.getRight() == null && root.getLeft() == null)
{
// The node has no children (full)
return true;
}
else if (root.getLeft() != null && root.getRight() != null)
{
// There are two children. Tree is only full if both sub trees are full
return isFull(root.getLeft()) && isFull(root.getRight());
}
else
{
// Only one child
return false;
}
All the algoritms above return true in this case (as they shouldn't):
complete binary tree
. So, hope this helps:
//-1 means "false"
public boolean full() {
int high = 0;
return ( root != null && isFull(root, high) != -1 );
}
public boolean isLeaf() {
return node.getRight() == null && node.getLeft() == null;
}
private int isFull(TreeNode<T> node, int high)
{
++high;
if (node.isLeaf())
return high;
else
{
int hLeft=0, hRight=0;
if(node.getLeft() != null)
hLeft = isFull(node.getLeft(), high);
if(node.getRight() != null)
hRight = isFull(node.getRight, high);
if ( (hLeft == hRight) && (hLeft != -1) )
return ++high;
return -1;
}
}
I can't seem to think of a way to solve this. At least not an elegant way. The function should determine if a given tree is a binary search tree. It seems to work (no duplicates are allowed now though).
This is where the function starts:
isBinarySearchTree(root)
Function:
public static boolean isBinarySearchTree(Node node) {
if (node.leftchild != null) {
if (node.leftchild.key < node.key)
isBinarySearchTree(node.leftchild);
else {
System.out.println("false: " + node + " -> " + node.leftchild);
return false;
}
}
if (node.rightchild != null) {
if (node.rightchild.key > node.key)
isBinarySearchTree(node.rightchild);
else {
System.out.println("false: " + node + " -> " + node.rightchild);
return false;
}
}
return true;
}
Obviously there is something wrong with the way I want to return. This would work if all the boolean return values would be in a logical && chain. The return value should only be true if all return values are true.
How would I have to rewrite the function to work like that? Or is it even possible?
This should work, I guess :
public static boolean isBinarySearchTree(Node node, int key) {
if (node.leftchild != null && node.leftchild.key < key || node.rightchild != null && node.rightchild.key > key) {
return false;
} else {
return (node.leftchild != null ? isBinarySearchTree(node.leftchild, node.leftchild.key) : true) && (node.rightchild != null ? isBinarySearchTree(node.rightchild, node.rightchild.key) : true);
}
}
You need to logically AND the results of your test on the left and test on the right, and return the result, something like return (leftnode == null || (leftnode.key < key && isBinarySearchTree(leftnode))) && (rightnode == null || (key < rightnode.key && isBinarySearchTree(rightnode)));. It might be clearer to break that into several lines, though.
public static boolean isBinarySearchTree(Node node) {
if(node==null)
return false;
if(node.left!=null &&node.key <node.left||node.right!=null &&node.key >node.right)
return false;
if((getMax(node.left)>getMin(node.right)) //Left subtree should not have a value which larger than min in right subtree
return false;
//check recurisvely left and right subtrees
if(!(isBinarySearchTree(node.left)&&isBinarySearchTree(node.right)))
return false;
return true;
I have a binary search tree. I know how to search using the search property. But my task is to search the tree without using search property.(Say, search in binary tree) This is how I have to search.
1. If you find the value in the current node return it.
2. else search in right. If not found in right, then search in left
3. If not found in the whole tree return null.
This is what i tried.
public Node search(int val)
{
Node target = this;
if(target.getVal() == val)
return this;
else if(target.getRight() == null && target.getLeft() == null)
return null;
if(target.getRight() != null)
{
return target.getRight().search(id);
}
if(target.getLeft() != null)
{
return target.getLeft().search(id);
}
return null;
}
Problem with my code is, if right child exists and val is not found in right I'm getting null value. (Not searching in left). How to resolve this?
public Node search(int val)
{
Node target = this;
if(target.getVal() == val)
return this;
else if(target.getRight() == null && target.getLeft() == null)
return null;
if(target.getRight() != null)
{
return target.getRight().search(id); //here lies the problem
}
if(target.getLeft() != null)
{
return target.getLeft().search(id);
}
return null;
}
The problem in your code is that you are returning the result of search in right subtree of the node being searched.
Here's the updated code
public Node search(int val)
{
Node target = null;
if(this.getVal() == val)
{
return this;
}
else if(this.getRight() == null && this.getLeft() == null)
return target;
if(this.getRight() != null)
{
target = this.getRight().search(id);
}
if(target==null && this.getLeft() != null)
{
target = this.getLeft().search(id);
}
return target;
}
This is untested code, but I'd change your logic a bit:
public Node search(int val)
{
if(this.getVal() == val)
return this;
if (this.getRight() != null) {
Node right = this.getRight().search(id);
if (right != null)
return right;
}
if (this.getLeft() != null) {
Node left = this.getLeft().search(id);
if (left != null)
return left;
}
return null;
}
In your version you are returning a solution with the sole requirement that the node on the right or left is not null. You have to return a solution only if a solution is found.
I've been asked to write a recursive method to investigate whether or not there are any single children. I have get the base cases but am a bit confused about how to go about the recursive section as I will need to investigate both the right and the left subtree and return false if one of them has a single child and true if one of them has 0 children or recur.
what I have so far is:
public static boolean noSingleChildren( BinaryTreeNode t ) {
if (rightC == null || leftC == null) {
return false;
} else if (rightC == null && leftC == null) {
return true;
} else {
return............
}
}
The logic is quite simple:
If the current node only has a single child, you're done.
Otherwise, recursively ask each non-null child the same question, and combine the answers using logical "or".
Since this looks like homework, I leave the implementation to you.
public static boolean noSingleChildren( BinaryTreeNode t ) {
if (rightC == null || leftC == null) {
return false;
} else if (rightC == null && leftC == null) {
return true;
} else {
return noSingleChildren(t.getLeftBranch()) || noSingleChildren(t.getRightBranch());
}
}
Ho, I love trees questions:
public static boolean hasSingleChildren( BinaryTreeNode t ) {
if (t == null) {
return false;
} else if (t.rightC == null && t.leftC != null) {
return true;
} else if (t.rightC != null && t.leftC == null) {
return true;
} else {
return hasSingleChildren(t.rightC) || hasSingleChildren(t.leftC);
}
}