Issue with function to check if tree is a BST - c++

So I have a function to check if a tree is a bst(if every node only has smaller values on its left and larger values on its right). Every other function works and the problem is with this one (second one just calls helper). I think the issue has something to do with the recursive call root-left hitting null but I am not sure and even if it is not sure how to fix. Can add more code as needed. Any help is appreciated.
visual studio error i get is : R00t -> left was nullptr
other compiler: segmentation fault core dumped.
bool isBSThelper(TreeNode* R00t)
{
if (R00t == NULL)
return true;
//if (R00t->left != NULL && (R00t->info < R00t->left->info))
if (R00t->info < R00t->left->info)
return false;
//if (R00t->right != NULL && (R00t->info < R00t->right->info))
if (R00t->info > R00t->right->info)
return false;
return isBSThelper(R00t->left) && isBSThelper(R00t->right);
}
bool TreeType::isBST() const
{
return isBSThelper(root);
}

According to your comment
even with if (R00t->left != NULL || R00t->right != NULL) error persists
the problem would persist. Let me rewrite and iterate from there (since I can't comment to ask for clarification -new user). If your code was like
bool isBSThelper(TreeNode* R00t) {
if ( R00t == NULL )
return true;
if ( R00t->left != NULL || R00t->right != NULL ) {
if ( R00t->info < R00t->left->info )
return false;
if ( R00t->info < R00t->right->info )
return false;
}
return isBSThelper(R00t->left) && isBSThelper(R00t->right);
}
then you would potentially still encounter the same problem, since the expression
if (R00t->left != NULL || R00t->right != NULL) {
would still make this expression with values
R00t->left != NULL
but
R00t->right == NULL
evaluate to true.
One solution might be
To make sure R00T->left and R00t->right are either valid (pointing to a node) or NULL (preferably nullptr if you are using C++)
And code like this:
bool isBSThelper( TreeNode* R00t ) {
if ( R00t == NULL )
return true;
if ( R00t->left != NULL && R00t->info > R00t->left->info )
return false;
if ( R00t->right!= NULL && R00t->info > R00t->right->info )
return false;
return isBSThelper( R00t->left ) && isBSThelper( R00t->right );
}
And the problem would be no more. (1) is critical.
An additional note: Your code does not check
if (R00t->left != NULL && R00t->right!= NULL && R00t->left->info < R00t->right->info)
return false;
which is another property of a Binary Search Tree (or obviously using ">" instead of "<" here as you see fit).

Related

Function doesn't return default value

Here is my code:
bool BinarySearchTree::CheckIfTreeIsBinary(){
bool isBinary=true;
isBinary=CheckIfTreeIsBinaryPrivate(root); // So if my tree is binary, this function does not return anything
// and isBinary should remain true, but it is false.
return isBinary;
}
bool BinarySearchTree::CheckIfTreeIsBinaryPrivate(nodePtr Ptr){
if(Ptr->left!=NULL){
CheckIfTreeIsBinaryPrivate(Ptr->left);
}
if(Ptr->left!=NULL){
if(Ptr->data<Ptr->left->data)
return false; // possibility 1 to return false
}
if(Ptr->right!=NULL){
if(Ptr->data>Ptr->right->data)
return false; // possibility 2 to return false
}
if(Ptr->right!=NULL){
CheckIfTreeIsBinaryPrivate(Ptr->right);
}
}
In my function CheckIfTreeIsBinary, I have set boolean isBinary to true for default value. After that, isBinary is assigned to function CheckIfTreeIsBinaryPrivate, which will not return anything if the tree is binary.
The problem is that function CheckIfTreeIsBinaryPrivate doesn't return anything if the tree is binary, but in the end, isBinary is false.
The problem is that CheckIfTreeIsBinaryPrivate does not have an explicit return value on all program control paths.
That means that the behaviour of your program is undefined.
Your compiler will warn you of this, and it's your job to heed those warnings.
Your recursive logic is incorrect. All paths in a function should return a value and you should always check the return value of recursive calls to CheckIfTreeIsBinaryPrivate. There's no concept of 'a value remaining the same'. Here's what I think you are trying to achieve, but it's quite complicated.
bool BinarySearchTree::CheckIfTreeIsBinaryPrivate(nodePtr Ptr) {
return
// check the left sub tree is ok
(Ptr->left == NULL || // NULL is ok OR
(Ptr->data >= Ptr->left->data && // data >= left->data && left is ok
CheckIfTreeIsBinaryPrivate(Ptr->left))) &&
// and check the right sub tree is ok
(Ptr->right == NULL || // NULL is ok OR
(Ptr->data <= Ptr->right->data && // data <= right->data && right is ok
CheckIfTreeIsBinaryPrivate(Ptr->right)));
}
I think I see where your misunderstanding is; you're expecting isBinary to be updated only if CheckIfTreeIsBinaryPrivate returns a value.
That's not how it works - a function that has a non-void return type must always return something.
If the function doesn't explicitly return anything - for instance, by reaching the end of the function - the program has undefined behaviour.
There is no way for you to determine whether a function returned anything or not, and you must return something on every path through the function.
You can do this with one big expression,
bool BinarySearchTree::isBST(nodePtr Ptr){
return Ptr == nullptr
|| ( (Ptr->left == nullptr || (Ptr->left->data < Ptr->data && isBST(Ptr->left)))
&& (Ptr->right == nullptr || (Ptr->right->data > Ptr->data && isBST(Ptr->right))));
}
or piece by piece:
bool BinarySearchTree::isBST(nodePtr Ptr){
// An empty tree is a BST.
if (Ptr == nullptr)
return true;
// If the left subtree is not a BST, neither is the entire tree.
else if (Ptr->left != nullptr && (Ptr->left->data > Ptr->data || !isBST(Ptr->left)))
return false;
// If the right subtree is not a BST, neither is the entire tree.
else if (Ptr->right != nullptr && (Ptr->right->data < Ptr->data || !isBST(Ptr->right)))
return false;
// All tests passed.
else
return true;
}
Add one more base condition in CheckIfTreeIsBinaryPrivate() to set true,
because once you assign isBinary to CheckIfTreeIsBinaryPrivate() it will set false by default, and you need a return value to get true.

Java8: Implement multiple conditional statements with stream API

I have a code block that redirects a Cassandra query to different Cassandra tables based on the available parameters such that I check multiple logical conditions inside multiple if conditions. I'm trying my hand at java 8 and looking to reduce these conditions to lambda expressions. Here's how the code currently looks,
String processTable(String cid, String postcode, String[] ratingvalue, String ratingType) {
String table = "";
if (postcode != null && ratingvalue == null) {
table = cassconf.getTable1();
}
if (postcode != null && ratingvalue != null) {
table = cassconf.getTable2();
}
if (cid != null && ratingvalue == null) {
table = cassconf.getTable3();
}
if (cid != null && ratingvalue != null) {
table = cassconf.getTable4();
}
if (cid != null && postcode != null && ratingvalue == null) {
table = cassconf.getTable5();
}
if (cid != null && postcode != null & ratingvalue != null) {
table = cassconf.getTable6();
}
return table;
}
My problem is even if I store the arguments in a map and filter the unavailable values from the stream, I don't know how to return the final value of the table based on these 6 different conditions.
Considering that ratingvalue can only be null or non-null, you can simplify the code by writing effectively unconditional statements as such:
String processTable(String cid, String postcode, String[] ratingvalue, String ratingType) {
if (cid != null)
if(postcode != null)
return ratingvalue == null? cassconf.getTable5(): cassconf.getTable6();
else
return ratingvalue == null? cassconf.getTable3(): cassconf.getTable4();
if(postcode != null)
return ratingvalue == null? cassconf.getTable1(): cassconf.getTable2();
return "";
}
Testing the conditions with precedence first is also more efficient than testing all conditions in reversed order and overwriting results of previous evaluations.
You could also write the entire evaluation as a single condition:
String processTable(String cid, String postcode, String[] ratingvalue, String ratingType) {
return cid != null?
postcode != null? ratingvalue == null? cassconf.getTable5(): cassconf.getTable6():
ratingvalue == null? cassconf.getTable3(): cassconf.getTable4():
postcode != null? ratingvalue == null? cassconf.getTable1(): cassconf.getTable2():
"";
}
An alternative is to use a map lookup:
String processTable(String cid, String postcode, String[] ratingvalue, String ratingType) {
final int hasCID = 1, hasPostcode = 2, hasRatingValue = 4;
Map<Integer, Supplier<String>> map = new HashMap<>();
map.put(hasCID|hasPostcode, cassconf::getTable5);
map.put(hasCID|hasPostcode|hasRatingValue, cassconf::getTable6);
map.put(hasCID, cassconf::getTable3);
map.put(hasCID|hasRatingValue, cassconf::getTable4);
map.put(hasPostcode, cassconf::getTable2);
map.put(hasPostcode|hasRatingValue, cassconf::getTable1);
return map.getOrDefault(
(cid!=null? hasCID: 0) | (postcode!=null? hasPostcode: 0)
| (ratingvalue!=null? hasRatingValue: 0),
() -> "").get();
}
The key point of this alternative is that, depending on what cassconf is or when it will be initialized, the map may be prepared at an earlier stage and processTable could be simplified to the return map.getOrDefault… operation.
I was thinking this as an exercise more, nothing to do with streams though, since it can't really help you here.
You could compute a HashMap that will have O(1) time for finding a value, like so:
Map<Integer, String> map = new HashMap<>(16);
map.put(0b1110, "table-6");
map.put(0b1100, "table-5");
map.put(0b1010, "table-4");
map.put(0b1000, "table-3");
map.put(0b0110, "table-2");
map.put(0b0100, "table-1");
This corresponds to whether your cid (the 4-th most significant bit), postcode (3-rd most significant bit) and ratingValue (second most significant bit) are null or not. So these are the total of 6 combinations that you are looking for.
Also this Map will have one entry per bucket, thus finding the value that you are interested in, will be really fast.
Computing the key that you need to get the value from is fairly trivial, you just need to set the bit (value that is not null).
String processTable(String cid, String postcode, String[] ratingvalue, String ratingType) {
if (cid != null) {
x = x | 1 << 3;
}
if (postCode != null) {
x = x | 1 << 2;
}
if (ratingValue != null) {
x = x | 1 << 1;
}
return map.get(x);
}
Do note that this code was take just as an exercise (well, we do have something close to this in real life, but there are compelling reasons for this - speed mainly).
Java 8 is not a magic wand you can simply wave at a piece of code to instantly improve it's readability.
Using null as a sentinel is bad practice and that's fundamentally why your code is hard to read. I suggest you rethink having nullable parameters.
Without fixing that, this is probably the best you can do:
if (ratingvalue == null)
{
if (cid != null && postcode != null) {
table = cassconf.getTable5();
}
else if (postcode != null) {
table = cassconf.getTable1();
}
else if (cid != null) {
table = cassconf.getTable3();
}
}
else
{
if (cid != null && postcode != null) {
table = cassconf.getTable6();
}
else if (postcode != null) {
table = cassconf.getTable2();
}
else if (cid != null) {
table = cassconf.getTable4();
}
}

Why is the IF (A || B) condition evaluated TRUE when one of its condition is FALSE?

private void case1(Tree t, Tree root) {
//System.out.println(root.left != t);
if (root.left != t || root.right != t)
case1(t, (root.value > t.value) ? root.left : root.right);
else {
if (root.left == t)
root.left = null;
else
root.right = null;
}
Why is the first IF condition evaluated TRUE even when root.left is actually equal to 't'? I have verified with print to console and the first condition does come out to be false. So the IF condition should be false, but the statement is still evaluated. The entire code is pretty big; I can provide more snippets if necessary.
Use && as || is for (OR) operator as if even one statement is true it will return true and in case of (AND) the both statements in if must be true only then it will return true.

2 Unequal strings are returned with true value on == as well as a.compare(b)

I'm making a BST & AVL tree working on string keys.
In the main , I've not added the "600" key but on finding it shows "600" found.
I tried debugging using gdb & found out that on 2 unequal strings == gave a true value passed my if clause.
I also tried using compare() function of string class, still the same problem.
Please Help !
This is my findNode function:
template<class NodeType>
NodeType* Tree<NodeType>::findNode(string key, NodeType* node)
{
if ( node == NULL )
return NULL;
else if ( node->Key() == key )
return node;
else if ( key < node->Key() )
findNode(key, node->Left());
else if ( key > node->Key() )
findNode(key, node->Right());
else
return NULL;
}
Here is the link to all of the code
https://github.com/tshrjn/ADSA/blob/master/bst.cpp
in your findNode method, you're missing return on the recursive calls to findNode(...left...) and findNode(...right...):
template<class NodeType>
NodeType* Tree<NodeType>::findNode(string key, NodeType* node)
{
if ( node == NULL )
return NULL;
else if ( node->Key() == key )
return node;
else if ( key < node->Key() )
return findNode(key, node->Left());
else if ( key > node->Key() )
return findNode(key, node->Right());
else
return NULL;
}
Your implementation returned garbage in these cases (which are most cases).
If you compiled with the -Wallflag, then the compiler would have found this error for you.
Btw, there are several more errors found by this flag, you might want to check it out.

Shift + Numpad1 keys not working?

//I want to change gear in my dash bord ,but there is no out but of these keys
if(pMsg->wParam==VK_SHIFT && pMsg->wParam==VK_NUMPAD1)
{
m_name.SetVariable("gear","1");
}
The expression (pMsg->wParam==VK_SHIFT && pMsg->wParam==VK_NUMPAD1) is always false.
Try this instead:
if ( (pMsg->wParam == VK_NUMPAD1) && (GetKeyState(VK_SHIFT) & 0x80) != 0) )
{
m_name.SetVariable("gear","1");
}
You also may consider the use of an accelerator table instead.