I want to implement a lazy deletion into my code. I have added a boolean value to keep track of when a node is "deleted"/marked deleted. I am unsure of what methods to actually change. Here are my remove and insert methods. I attempted the remove, but not the insert. I know for sure that the insert method will have to do a lot of checking. Please advise.
template<class Comparable>
bool search_tree<Comparable>::remove(treeNode<Comparable> * &root,
const Comparable &x) {
if (root == NULL)
return false;
if (x < root->data)
return remove(root->lftChild, x);
if (root->data < x)
return remove(root->rtChild, x);
root->deleted = true;
return true;
}
template<class Comparable>
bool search_tree<Comparable>::insert(treeNode<Comparable> * &root,
const Comparable &x) {
if (root == NULL) {
root = new treeNode<Comparable>(x, NULL, NULL);
return true;
} else if (x < root->data)
return insert(root->lftChild, x);
else if (root->data < x)
return insert(root->rtChild, x);
return false;
}
Your insert function should work as is unless x is equal to an item that has been deleted then it wont get inserted. If x is equal to root->data you need to make sure deleted is false.
And your remove function looks like it should work fine.
Related
bool search(double x, TreeNode *t)
{
if (t->value == x)
return true;
else if (x < t->value)
search(x, t->left);
else if (x > t->value)
search(x, t->right);
return false;
bool search(double num)
{
TreeNode *ptr = root;
return search(num, ptr);
}
The search function with 2 arguments is a private member function of a binary tree class that uses recursion to search for a value. The other search function is called to call the recursive function. This code does not work. I have displayed the value of the recursive function and it does not return 0 or 1. I have no idea why. Also, if I send in a value that is not in the tree, the program crashes so I get no errors to help me.
Your recursion never stops if you don't find an element.
If it's found in the root, you return true.
If it's found somewhere else, you return false.
You need to
Handle the empty tree, and
Return something meaningful when recursing.
Like
bool search(double x, const TreeNode *t)
{
if (t == nullptr)
return false;
else if (t->value == x)
return true;
else if (x < t->value)
return search(x, t->left);
else
return search(x, t->right);
}
or
bool search(double x, const TreeNode *t)
{
return t != nullptr
&& ( t->value == x
|| (t->value < x && search(x, t->left))
|| (t->value > x && search(x, t->right)));
}
I am writing a method to check if a given tree is a BST using the inorder traversal method. On executing this method, I get a segfault. Can someone help me correct it?
here, maximum stores the largest value in the BST, and k is initialized to 0. The BST is assumed to have unique positive values. isNull(root) checks if the current node is a null node or not.
bool check(BstNode* root)
{
if (root->data==maximum) return true;
isNull(root);
check(root->left);
if (root->data>k)
{
k=root->data;
}
else
{
return false;
}
check(root->right);
}
Every time when you call check(root->left) and check(root->right), I suppose you need to add sth to determine the left and the right branch is null or not. In your code, you just assume that there is sth in left and right branch and call the check function. I think that's the main reason.
You shouldn't need to specify the maximum value. An elegant solution can be found here
There are two approaches you can do this.
One is top-down approach, first check if current node is valid, if so, then check two subtree. This is very intuitive. you can find the code from #lerman's post:
struct TreeNode {
int data;
TreeNode *left;
TreeNode *right;
};
bool isBST(TreeNode *node, int minData, int maxData) {
if(node == NULL) return true;
if(node->data < minData || node->data > maxData) return false;
return isBST(node->left, minData, node->data) && isBST(node->right, node->data, maxData);
}
if(isBST(root, INT_MIN, INT_MAX)) {
puts("This is a BST.");
} else {
puts("This is NOT a BST!");
}
The other way is a bottom-up approach: first check left substree then right substree and check current tree at last. below is the code for this approach.
bool isValidBST(TreeNode *root) {
int mmin, mmax;
return helper(root, mmin, mmax);
}
bool helper(TreeNode* root, int& mmin, int& mmax) {
if(!root) {
mmin = INT_MAX;
mmax = INT_MIN;
return true;
}
int leftmin, leftmax, rightmin, rightmax;
if(!helper(root->left, leftmin, leftmax))
return false;
if(!helper(root->right, rightmin, rightmax))
return false;
if(root->val > leftmax && root->val < rightmin) {
mmin = min(min(leftmin, rightmin), root->val);
mmax = max(max(leftmax, rightmax), root->val);
return true;
}
else
return false;
}
You might notice that the first approach is pre-order traversal and the second approach is post-order traversal. inorder traversal in inappropriate here because it conflicts with the definition of BST.
I have to check if a tree is a binary search tree. I'm doing this with an inorder traversal with a temporary array that collects the values. I have to check if the array is ascending order and if it is then I return true:
bool myisBST(Node* node, std::vector<int> v);
bool myisBST(Node* node)
{
return myisBST(node, std::vector<int>());
}
bool myisBST(Node* node, std::vector<int> v)
{
if (node)
{
if (node->left)
return myisBST(node->left, v);
v.push_back(node->data);
if (node->right)
return myisBST(node->right, v);
}
return std::is_sorted(v.begin(), v.end());
}
When binary tree is this:
50
/ \
25 75
/ \ / \
1 12 62 -99
As you can see, the -99 makes this not a binary search tree, but it is still returning true. Is there something wrong with my implementation?
Demo
Two problems:
In myisBST, you are passing v by value, not by reference, so when you pass the vector on recursively, the changes that are made to it don't change its value in the calling method. Simply change the function signature to bool myisBST(Node* node, std::vector<int>& v) to fix this.
The value you should be returning is whether the vector is sorted (as you do in the last line of your method), but instead you are returning prematurely by writing return myisBST(node->left, v); and return myisBST(node->right, v);. You're not actually interested in the return values of these methods; you're just using them to fill the vector inorder. Remove the return from both of these lines.
Following these two fixes, your method works.
First of all, you should probably pass the vector by reference or each recursive call will get a copy and thus the original vector will probably be empty.
Second, you don't even need to create the vector first and then do the check, you can just check the BST property at each node, i.e., the root must be bigger than the left child and smaller than the right child, e.g.,
bool isBST(const Node* root, vector<int>* v) {
if (!root) { return true; }
bool leftBST = true;
if (root->left) {
if (root->data > root->left->data) {
leftBST = isBST(root->left, v);
} else {
// the current node violates the BST precondition
return false;
}
}
// push the root
v->push_back(root->data);
// return false if left subtree is not a BST
if (!leftBST) return false;
if (root->right) {
if (root->data < root->right->data) {
// return whether or not the right subtree is a BST
return isBST(root->left, v);
} else {
// the current node violates the BST precondition
return false;
}
}
// everything good, this is a BST
return true;
}
C++ Program to check if tree is BST or not
struct Node
{
int data;
struct Node* left, *right;
};
bool IsBST(Node* ObjNode)
{
bool leftBST = false;
bool rightBST = false;
if( ObjNode->left != null && ObjNode-left < objNode->data)
{
leftBST = IsBST(ObjNode->left)
}
else if( ObjNode->left == null)
{
leftBST = true;
}
else if( ObjNode->left != null && ObjNode-left >= objNode->data)
{
leftBST = false;
}
if( ObjNode->left != null && ObjNode-left < objNode->data)
{
rightBST = IsBST(ObjNode->right)
}
else if( ObjNode->right == null)
{
rightBST = true;
}
else if( ObjNode->right != null && ObjNode-right >= objNode->data)
{
rightBST = false;
}
return (leftBST && rightBST );
}
In the previous solution, they are keeping a list of the inorder traversal, you really don't need it, you can keep checking with the last traversed element and keep moving forward.
Following solution is the fastest
class Solution {
int lastval = Integer.MIN_VALUE;
int count = 0;
public boolean isValidBST(TreeNode root) {
if(root == null) return true;
boolean left = isValidBST(root.left);
if(!left){
return false;
}
int rootVal = root.val;
if(rootVal == -2147483648 && count == 0 ){
rootVal = rootVal + 1;
}
if( rootVal <= lastval){
return false;
}
count ++;
lastval = root.val;
boolean right = isValidBST(root.right);
if(!right){
return false;
}
return true;
}
}
and I was trying to implement a binary searching tree:
template <typename T>
bool Tree<T>::search(TreeNode<T> *ptr, const T &key) {
if (ptr == 0) {
cout<<"No such data: "<<key<<" in the tree"<<endl;
return false;
}
else{
if (ptr->data == key) {
cout<<"Find a node whose data is "<<key<<endl;
return true;
}
else if (ptr->data < key) return search(ptr->leftPtr,key);
else return search(ptr->rightPtr,key);
}
}
But the result always returns false no matter the tree contains the key value or not.
Can u guys help me check the code? I tried debug, but still do not know.
Thank you!
Your traversal comparator for left-tree descending is backwards. As such, as soon as you incorrectly descend into the right tree you stand no chance of ever finding that value. Only the root, and root only, will ever be found correctly.
This:
if (ptr->data < key)
return search(ptr->leftPtr,key);
else
return search(ptr->rightPtr,key);
Should read like this:
if (key < ptr->data) // <== note key is LESS THAN node.
return search(ptr->leftPtr,key);
else
return search(ptr->rightPtr,key);
That said, consider this:
template <typename T>
bool Tree<T>::search(TreeNode<T> *ptr, const T &key)
{
if (ptr == 0) {
cout<<"No such data: "<<key<<" in the tree"<<endl;
return false;
}
if (key < ptr->data)
return search(ptr->leftPtr, key);
else if (ptr->data < key)
return search(ptr->rightPtr, key);
cout<<"Found a node whose data is "<< key << endl;
return true;
}
I am trying to implement one bool function that receives List and Int as arguments and should insert int and return true if the int does not exist in the list, or false if it is already there, i have been working for several hours with this function, and the if-else statements can insert sorted int, the problem (and crash) is how to check if the value already exist and return false, here is my function:
declaration of struct
typedef struct E_Type * List;
struct E_Type
{
int data;
List next = 0;
};
and function
bool insert(List & l, int data)
{
List current = l;
do{//check if the int is already in the list
current->data;
current = current->next;
//return false;
}while (current->data == data);
if (l == 0 || l->data > data){
List new_list = new E_Type;
new_list->data = data;
new_list->next = l;
l = new_list;
return true;
}
else if(l->data < data){
insert(l->next, data);
return true;
}
}
do{
//this line doesn't really do anything...
current->data;
//moving current forward, good.
current = current->next;
//If current->data is less than data in the list, it will exit the loop here anyway.
}while (current->data == data);
You also aren't checking whether you have reached the end of the list. Perhaps what you are attempting to do is something like this:
//This is correct for for iterative approach, but I don't think this is really what you need, either...
while(current != null) {
if (current->data == data)
return false;
current = current->next;
}
However, you probably don't want to use iteration like this to make this check in a recursive function, so instead, simply replace that whole bit with:
if (current->data == data)
return false;
And to return the correct value through the recursive calls, you'll want to change:
else if(l->data < data){
insert(l->next, data); //Recursive call
return true; //you don't want to just return true, return what the recursive call returns!
}
To:
else if(l->data < data){
return insert(l->next, data);
}