Error in finding lowest common ancestor in tree - c++

I am trying to find the lowest common ancestor of the two given values in the tree.
My approach is to traverse to the bottom left of the tree and check individual nodes weather they have both the nodes under them. The first node to give a match is the lowest common ancestor.
Can anyone tell me the error in this function.
/*
Node is defined as
typedef struct node
{
int data;
node * left;
node * right;
}node;
*/
bool find(node *root,int val) //to check if the value exist under the given node or not
{
if(root==NULL)
return false;
if(root->data==val)
return true;
if((root->left&&find(root->left,val))||(root->right&&find(root->right,val)))
return true;
return false;
}
node * lca(node * root, int v1,int v2) //to find the lowest common ancestor
{
if(root==NULL)
return NULL;
static node* ans=NULL;
lca(root->left,v1,v2); //traversing to the bottom of the tree
lca(root->right,v1,v2);
if((find(root->left,v1)&&find(root->right,v2))||(find(root->left,v2)&&find(root->right,v1))) //checking the existence of both nodes under the tree
{
if(ans==NULL)
ans=root;
}
return ans; //returning the lca
}

Your recursive function should return only a node if the result was found. It should return NULL if the result node was not found. Break if the node was found, else continue. I would do it like this:
node * lca(node * root, int v1,int v2) //to find the lowest common ancestor
{
if(root==NULL)
return NULL;
node* ans=NULL;
// search the left child tree
ans = lca(root->left,v1,v2);
if (ans != NULL)
return ans; // if you found it you are finished
// search the right child tree
ans = lca(root->right,v1,v2);
if (ans != NULL)
return ans; // if you found it you are finished
// test this tree node
if( (find(root->left,v1)&&find(root->right,v2)) ||
(find(root->left,v2)&&find(root->right,v1)))
{
// If the condition is true, this node is the result
return root;
}
return NULL; // Neither this node nor any subordinate node of this node is the result
}

Related

How would I recursively traverse a tree that returns a bool

I have to complete a function that will return true if a "tree" has a node that points back to itself or if a node has descendants that point back to it. The tree has at most one of these loops for every call.
struct Node
{
Node* left;
Node* right;
int data;
}
bool finder(Node* root, vector<Node*> cd) // helper
{
for (unsigned int i = 0; i < cd.size(); i++)
if (cd[i] == root) return true;
return false;
}
bool Looper(Node* root, vector<Node*> cd)//finder will be called to compare
the next node against the visited nodes.
{
returns false;
}
I know I need to traverse the tree and mark each node by putting it in the vector, but I have no idea what traversal to do or how to do it. Any ideas?
Potential solution:
bool Looper(Node* root, vector<Node*> cd){
vector<Node*> visited;
if(finder(root,visited))
return true;
if(root==nullptr)
returnvalue = false;
if(!finder(root,visited))
{
visited.push_back(root);
return Looper(root->left,visited);
return Looper(root->right,visited);
}
return false;
}
#include <iostream>
#include <vector>
struct Node
{
// some other stuff...
int id;
std::vector<Node*> children;
};
bool finder(Node* root, Node* currentNode, std::vector<bool>& visited)
{
visited[currentNode->id] = true;
for (Node* node : currentNode->children)
if (node == root)
{
std::cout << currentNode->id << '\n';
return true;
}
else if (!visited[node->id] && finder(root, node, visited))
{
return true;
}
visited[currentNode->id] = false;
return false;
}
bool Looper(Node* root, int n)
{
std::vector<bool> visited(n, false);
return finder(root, root, visited);
}
int main()
{
Node n0{ 0 };
Node n1{ 1 };
Node n2{ 2 };
Node n3{ 3 };
n0.children.push_back(&n1);
n0.children.push_back(&n2);
n1.children.push_back(&n3);
n3.children.push_back(&n0);
if (Looper(&n0, 4))
std::cout << "Found\n";
}
Output:
3
Found
Since you want a child node that points to a parent, your tree will contain cycles. So you have to keep track of which nodes you've visited. That's why I keep track of the visited nodes. also I would recommend using std::vector to represent the tree instead of using nodes.
Here's my understanding of your task, simply call check_for_cycles with your tree's root node and an empty vector to detect a cycle in your tree.
bool check_for_cycles(Node* node, vector<Node*>& visited)
{
// null is a not a cycle
if (node == nullptr)
return false;
// have we been here before? if so we have a cycle
if (find(visited.begin(), visited.end(), node) != visited.end())
return true;
// mark this node as visited
visited.push_back(node);
// recursively check the sub trees
return check_for_cycles(node->left, visited) || check_for_cycles(node->right, visited);
}
Note a vector isn't the best choice for visited because of the time cost of checking if a node is present. An unordered_map would be better, and so would having a field in the node itself that you could mark.
This is untested code.

Accepting tree nodes from keyboard for determining it's height

I have a code that can determine tree height by hard coding it's values
I tried using container like structures but still was not successful, instead of posting what I have tried on the part of accepting tree nodes fro the Input which is actually messy,I decided to post the code with hard coded tree nodes, what I need is for the program to accept tree nodes from the keyboard with the following helper description for input
Input:
The first line is an integer N indicating the number of nodes.
For each of the next few lines, there are two integers include a and b.b is a child of a.
example:
5 // number of nodes
1 2
1 3
3 4
3 5
in which the height will be 3
// C++ program to find height of tree
#include <bits/stdc++.h>
using namespace std;
/* A binary tree node has data, pointer to left child
and a pointer to right child */
class node
{
public:
int data;
node* left;
node* right;
};
/* Compute the "maxDepth" of a tree -- the number of
nodes along the longest path from the root node
down to the farthest leaf node.*/
int maxDepth(node* node)
{
if (node == NULL)
return 0;
else
{
/* compute the depth of each subtree */
int lDepth = maxDepth(node->left);
int rDepth = maxDepth(node->right);
/* use the larger one */
if (lDepth > rDepth)
return(lDepth + 1);
else return(rDepth + 1);
}
}
/* Helper function that allocates a new node with the
given data and NULL left and right pointers. */
node* newNode(int data)
{
node* Node = new node();
Node->data = data;
Node->left = NULL;
Node->right = NULL;
return(Node);
}
// Driver code
int main()
{
node *root = newNode(1);
root->left = newNode(2);
root->right = newNode(3);
root->left->left = newNode(4);
root->left->right = newNode(5);
cout << "Height of tree is " << maxDepth(root);
return 0;
}
Since the input identifies the parent node by its data value, we need a helper function to find it:
node *findNode(node *node, int data)
{
if (!node) return 0;
if (node->data == data) return node;
class node *found;
(found = findNode(node->left, data)) || (found = findNode(node->right, data));
return found;
}
Then we can code the input processing, e. g.:
node *node, *root = 0; // initially empty
int nn, a, b;
cin>>nn;
while (cin>>a>>b)
{
if (!root)
root = newNode(a),
node = root;
else
node = findNode(root, a);
if (!node->left) node->left = newNode(b);
else node->right = newNode(b);
}

Runtime error while recursively calling a function with a double pointer as its default argument in c++

What I am trying to do:
I am trying to delete a node in a binary search tree. But before deleting the node we first have to search if the node exists and that I am checking in my search function which returns the address of the node where the match is found.
What is the problem:
After execution, the program throws an exception: Process returned -1073741819 (0xC0000005) And I believe the problem is with the statement (*parent) = root;But I don't know why it does so. And how to fix it.
My code:
Struct Defined As:
struct tree{
int data;
struct tree *left, *right;
};
Search function:
tree * search(tree *root, int value, tree **parent = NULL){
tree * target = NULL;
if (!root) return root;
if (root->data == value) return root;
if (value < root->data){
// This returns the matched node
target = search(root->left, value);
// and this stores the parent of the matched node
if (root->left->data == value)
(*parent) = root;
} else {
target = search(root->right, value);
if (root->right->data == value)
(*parent) = root;
}
return target;
}
Delete function:
void del(tree *root, int value){
tree * parent = NULL;
if (!root) return;
tree *target = search(root, value, &parent);
// Deletion logic goes here
}
The simple reason is that *parent=... is an assignment. That requires that parent is a valid (non-null) pointer. Yet you use nullptr as the default value of parent.
You'll need to fix the design of this function. This is not the only flaw.

Construction of Binary Search Tree from preorder traversal iteratively (not recursion)

The following is the code to converted a preorder traversal of a Binary Search Tree to the original tree.
The following code takes an array of integers, which represent the pre order traversal of a a Binary search tree. The root of the construct tree is returned.
struct Node* constructTree(int pre[], int size)
{
stack<struct Node* > s;
int i;
struct Node* root=newNode(pre[0]);
struct Node* temp;
struct Node* top_node;
s.push(root);
for(i=1;i<size;i++)
{
temp=NULL;
while(!s.empty()&&pre[i]>(s.top()->data))
{
temp=s.top();
s.pop();
}
if(temp==NULL)
{
top_node=s.top();
top_node->left=newNode(pre[i]);
s.push(top_node->left);
}else
{
temp->right=newNode(pre[i]);
s.push(temp->right);
}
}
return root;
}
Source: http://www.geeksforgeeks.org/construct-bst-from-given-preorder-traversal-set-2/
I have trouble understanding this code. Can anybody help me understand the following:
At any given iteration, what values are stored in the stack, in relation to the current value being pointed out by pre[i]
Is there any other iterative method for constructing a BST from a given preorder traversal?
Thank you.
After the iteration where the node containing pre[i] is constructed, the stack contains that node on top, under which its leafmost to rootmost ancestors with exactly one child are stored top to bottom.
Check if this works:
public:
TreeNode* bstFromPreorder(vector<int>& preorder) {
TreeNode *root = new TreeNode(preorder[0]);
stack<TreeNode*> nodes;
nodes.push(root);
for (int i = 1; i < preorder.size(); i++) {
TreeNode *temp = new TreeNode(preorder[i]);
if (temp->val < nodes.top()->val)
nodes.top()->left = temp;
else {
TreeNode *prev;
while (!nodes.empty() && nodes.top()->val < temp->val) {
prev = nodes.top();
nodes.pop();
}
prev->right = temp;
}
nodes.push(temp);
}
return root;
}

search in a binary tree

I have written the following function to search for a value in a binary tree storing integer values (the function is part of a larger program):
bool tree::search(int num) //the function belongs to class 'tree'
{
node *temp=head; //'head' is pointer to root node
while(temp!=NULL)
{
if(temp->data==num)
break;
if(num>temp->data)
temp=temp->right;
if(num<temp->data)
temp=temp->left;
}
if(temp==NULL)
return false;
else if(temp->data==num)
return true;
}
The problem is: when I search for a value present in the tree, it runs fine. But if I search for a value not present in the tree, the program just hangs, and I have to close it.
One more thing - I know we can implement the search function recursively by passing node *temp as an argument, instead of declaring it inside, and I have done so which caused the program to run correctly, but I want to know what is the problem in the above code.
I am giving the full program here, just in case it makes fault- finding easier( please note that I have written only two functions yet):
#include<iostream>
using namespace std;
struct node
{
int data;
node *left;
node *right;
};
class tree
{
public:
node *head; //pointer to root
int count; //stores number of elements in tree
tree();
void addnode(int);
void deletenode(int);
bool search(int);
int minimum();
int maximum();
void inorder();
void preorder();
void postorder();
void printtree();
int mthlargest(); //finds 'm'th largest element
int mthsmallest(); //finds 'm'th smallest element
void convert(); //converts binary tree to linked list
};
tree::tree()
{
head=NULL;
count =0;
}
void tree::addnode(int num)
{
node *temp= new node;
temp->data=num;
temp->left=NULL;
temp->right=NULL;
node **ptr=&head; //double pointer
while(*ptr!=NULL)
{
if(num>(*ptr)->data)
ptr=&((*ptr)->right);
if(num<(*ptr)->data)
ptr=&((*ptr)->left);
}
*ptr=temp;
}
bool tree::search(int num)
{
node *temp=head;
while(temp!=NULL)
{
if(temp->data==num)
break;
if(num>temp->data)
temp=temp->right;
if(num<temp->data)
temp=temp->left;
}
if(temp==NULL)
return false;
else if(temp->data==num)
return true;
}
int main()
{
tree ob;
ob.addnode(2);
ob.search(2);
ob.search(3);
ob.search(-1);
ob.search(2);
cout<<endl<<endl;
system("pause");
return 0;
}
Side note : I am using Dev C++ compiler and Windows 7 OS.
Put an else and your problem will disappear.
Because after temp = temp->right; you must check temp again but in your original code you immediately test temp->data which may not be a valid pointer.
bool tree::search(int num)
{
node *temp = head;
while (temp != NULL)
{
if (temp->data == num)
break;
if (num > temp->data)
temp = temp->right;
else // <--- Put this 'else' here
if (num < temp->data)
temp = temp->left;
}
if (temp == NULL)
return false;
if (temp->data == num)
return true;
return false;
}
std::set
Use a std::set; it is basically STL's binary tree. If you want to search for something, you would use count, find or lower_bound.
Implementing basic data structures are good exercises, but in production, try to use STL first, as they are implemented by professionals with specific knowledge of the compiler/platform in question. Boost is another great set of data structures and common idioms.