Alternative to boolean recursion - java

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;

Related

Given two trees, return true if they are structurally identical they are made of nodes with the same values arranged in the same way

public static boolean identical(treenode<Integer> root1,treenode<Integer> root2)
{
boolean ans;
for(int i=0;i<root1.children.size();i++)
for(int j=0;j<root2.children.size();j++)
{
boolean subans=identical(root1.children.get(i),root2.children.get(j));
ans=subans;
}
if(root1.data==root2.data)
{
ans=true;
}/* what's wrong with the code*/
else{
ans=false;
}
return ans;
}/* how can i improve it ? */
i am not able to understand why my code is not working.please tell me the solutions to fix it.
Your for loop is going through every recursive call of identical before evaluating the boolean return of those recursive calls. In other words, you're not evaluating the data of all of the children through your recursive calls. I believe with your code that you may only be evaluating the last child node of every node in the tree (going down the right-most side).
You also have a nested for loop, which is unnecessary in your case.
What I propose is this:
1) Check that the values of your current nodes are the same. If not, or if at least one is null, return false immediately.
2) Check that the sizes of the children are the same for both nodes. If not, return false.
3) Call this recursively with each child node.
This is a depth first, left-side-first search.
private boolean structurallyIdentical(Node tnode, Node onode) {
if(tnode == null && onode == null) {
return true;
}
if(tnode != null && onode != null) {
// check that the left branch is identical
boolean left = structurallyIdentical(tnode.left, onode.left);
// check that the right branch is identical
boolean right = structurallyIdentical(tnode.right, onode.right);
// only identical, if both branches match
return (left && right);
}
return false;
}
A little improvement based on #Vansh Nandwani's answer.
SBT = Same Binary Tree
public boolean SBT(BinNode root1, BinNode root2)
{
if (root1 == null && root2 == null) return true;
if (root1 != null && root1 != null) {
if (root1.value() == root2.value())//check if the values are the same
{
boolean left = SBT(root1.left(), root2.left());
boolean right = SBT(root1.right(), root2.right);
return (left && right);}
}
return false;
}
public class Solution {
/* TreeNode structure
class TreeNode<T> {
T data;
ArrayList<TreeNode<T>> children;
TreeNode(T data){
this.data = data;
children = new ArrayList<TreeNode<T>>();
}
}*/
public static boolean checkIdentical(TreeNode<Integer> root1, TreeNode<Integer> root2){
if(root1.children.size()!=root2.children.size())
{
return false;
}
if(root1.children.size()==root2.children.size()){
if(root1.data==root2.data)
{
for(int i=0 ,j=0;i<root1.children.size()&&j<root2.children.size();i++ ,j++){
checkIdentical(root1.children.get(i),root2.children.get(j));
return true;
}
}
}
return false;
}
}
bool areIdentical(TreeNode<int> *root1, TreeNode<int> * root2)
{bool ans=false;
if(root1->children.size()!=root2->children.size())
{
ans =false;
}
if(root1->children.size()==root2->children.size()){
if(root1->data==root2->data)
{
for(int j=0;j<root1->children.size();j++){
areIdentical(root1->children[j],root2->children[j]);
ans=true;
}
}
}
return ans;
}
For general tree
Method 1:
bool areIdentical(TreeNode<int> *root1, TreeNode<int> * root2) {
if(root1 == NULL && root2 == NULL){
return true;
}
if((root1 == NULL && root2 != NULL) || (root1 != NULL && root2 == NULL)){
return false;
}
if((root1->data != root2->data)|| (root1->children.size() != root2->children.size())){
return false;
}
else if(root1->children.size() == root2->children.size()){
if(root1->data == root2->data){
for(int i=0,j=0;i<root1->children.size()&&j<root2->children.size();i++,j++){
areIdentical(root1->children[i],root2->children[j]);
return true;
}
}
}
return false;
}
//this solution may fail some testcase but
Method 2 : work perfectly fine
Method 2 :
bool areIdentical(TreeNode<int> *root1, TreeNode<int> * root2) {
if(root1 == NULL && root2 == NULL){
return true;
}
if((root1 == NULL && root2 != NULL) || (root1 != NULL && root2 == NULL)){
return false;
}
if((root1->data != root2->data)|| (root1->children.size() != root2->children.size())){
return false;
}
for(int i = 0;i < root1->children.size();++i){
TreeNode<int>* child1 = root1->children[i];
TreeNode<int>* child2 = root2->children[i];
if(!areIdentical(child1,child2)){
return false;
}
}
return true;
}
Structurally identical
public static boolean checkIdentical(TreeNode<Integer> root1, TreeNode<Integer> root2){
int size1=root1.children.size();
int size2=root2.children.size();
if(root1==null && root2==null){
return true;
}
if((root1==null && root2!=null) || (root1!=null && root2==null)){
return false;
}
if((root1.data!=root2.data)||(size1!=size2)){
return false;
}
if(size1==size2){
if(root1.data==root2.data){
for(int i =0;i<size1;i++){
for(int j=0;j<size2;j++){
TreeNode<Integer> child1=root1.children.get(i);
TreeNode<Integer> child2=root2.children.get(i);
if(!checkIdentical(child1,child2)){
return false;
}
}
}
}
}
return true;
}

Check that sum of left and right children values equal value of the parent in Binary Trees?

I'm writing a method for a homework problem on binary trees.
Objective:
Given a binary tree, check if the tree satisfies the property that for each node, the sum of the values of its left and right children are equal to the node's value. If a node has only one child, then the node should have the same value as that child. Leaf nodes automatically satisfy the property.
I am getting an error that my code is not correct for all cases. For example if I have a tree
15
/ \
5 10
I am returning false when it should be true.
Here is my method so far, what am I doing wrong?
boolean BTchecksum(BinNode root) {
if (root == null || root.left() == null && root.right() == null) {return true;}
BinNode leftNode = root.left();
BinNode rightNode = root.right();
int sum = (int)(leftNode.element()) + (int)(leftNode.element());
int value = (int)(root.element());
return (sum == value) && BTchecksum(root.left()) && BTchecksum(root.right());
}
You wrote sum as:
leftNode.element()) + (int)(leftNode.element)));
Should be this:
leftNode.element()) + (int)(rightNode.element)));
Right now, you're probably getting null pointer exceptions because you're referencing children that may be null. This may not be the most efficient solution, but it takes care of all the cases.
public boolean BTchecksum(BinNode root) {
if (root == null || root.right()==null && root.left()==null) {
return true;
}
if (root.right() == null) {
return (root.left().value() == root.value())
&& BTchecksum(root.left());
} else if (root.left() == null) {
return (root.right().value() == root.value())
&& BTchecksum(root.right());
} else {
return (root.value() == root.left().value() + root.right().value())
&& BTchecksum(root.left()) && BTchecksum(root.right());
}
Revision (no NullPinterException)
public boolean BTchecksum(BinNode root)
{
if (root == null || root.left() == null && root.right() == null) {return true;}
int sum = 0;
if (root.left() != null){sum = sum + root.left().value();}
if (root.right() != null){sum = sum + root.right().value();}
return (sum == root.value()) && BTchecksum(root.left()) && BTchecksum(root.right());
}

Check if a binary tree is full in Java?

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;
}
}

Inversion of return value

I have a flag that I want to pass to a function which returns true or false based on a value in a map:
// userList is a List<String> and is stored as the value field in a map
// user is a String
if(flag)
{
if (userList == null)
return false;
else if(userList.size() == 0)
return true;
return userList.contains(user);
}
else
{
if (userList == null)
return true;
else if(userList.size() == 0)
return false;
return !userList.contains(user);
}
My question is this: is there anyway to tidy this code up, there is a lot of replication (the if and else block are identical, except their return values are the opposite of each other).
I'm not a very experienced code, and I'd really appreciate some guidance!
Use the flag value instead of constants.
if (userList == null)
return !flag;
else if(userList.size() == 0)
return flag;
A XOR will serve for the last statement (left as exercise to the reader :-p)
We can move the common processing to its own method, then branch based on the flag variable as follows.
public boolean userExists(String user) {
return userList != null && (userList.size() == 0 || userList.contains(user));
}
...
if(flag) return userExists(user);
else return !userExists(user);
As a side note, you may have a logic error. I'm not sure why you'd want to return true in the case of userList.size() == 0.
Here's a way to simplify the whole snippet of code, removing the outer if/else statement:
if (userList == null)
return !flag;
else if (userList.isEmpty())
return flag;
return userList.contains(user) == flag;
if (userList == null)
return !flag;
else if(userList.size() == 0)
return flag;
return flag ? userList.contains(user) : !userList.contains(user);ยท
You can easily remove duplication by making the return value be a function of flag :
if (userList == null) {
return !flag;
} else if (userList.size() == 0) {
return flag;
}
return !flag ^ userList.contains(user);
return userList != null && userList.contains(user) == flag;
Might do the job.

java - tree structure method

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);
}
}

Categories

Resources