Find ancestors of given node in a n-ary tree c++ - c++

Given a larg n-ary tree, I need to create a recursive function that prints all the ancestors of a leaf for example where the n-ary tree structure is given as
typedef struct sNaryNode
{
int *data;
int nchild;
struct sNaryNode **child;
} NaryNode;
Here is the function I used but that gives a wrong answer:
bool printAncestors(NaryNode *root, int *data)
{
int i=0;
if (root == NULL)
return false;
if (root->data == data)
return true;
do
{
auto b=printAncestors(root->child[i], data);
if(b)
{
cout<<*root->data<<" ";
return true;
}
else
i++;
}
while(i<root->nchild);
}

You're missing a return value at the end, and you may enter the loop and access root->child[i] even if root->nchild is zero.
Both of those will cause undefined behaviour.
I would write this with a for-loop instead:
bool printAncestors(const NaryNode *root, const int *data)
{
if (root == nullptr)
return false;
if (root->data == data)
return true;
for (int i = 0; i < root->nchild; i++)
{
if (printAncestors(root->child[i], data))
{
cout << *root->data << " ";
return true;
}
}
return false;
}

Related

Find if the binary search tree has duplicated value

For binary search tree to see if the tree has duplicated value or not. I took this post order approach.
My goal was to keep the value of the current node and then use other function traverse the tree to see if there is any matching value to that current value, and if it finds any duplicate value it brings "true value". I choose to use recursion as it seems easier to track. but when I ran the program there was no output coming out.
#include "pch.h"
#include <iostream>
using namespace std;
class BSTNode {
public:
int data;
BSTNode* left;
BSTNode* right;
BSTNode() {};
};
BSTNode* newnode(int newdata) { BSTNode *curr = new BSTNode; curr->data = newdata; curr->left = curr->right = nullptr; return curr; }
void print(BSTNode* root) {
if (root != nullptr) {
print(root->left);
cout << root->data << endl;
print(root->right);
}
}
bool checking(BSTNode* parent, int val) {
if (val == parent->data){
bool left = checking(parent->left, val);
bool right = checking(parent->right, val);
return left||right;
}
else
return false;
}
bool assist(BSTNode* parent) {
if (parent != nullptr) {
assist(parent->left);
assist(parent->right);
return checking(parent, parent->data);
}
else return false;
}
int main() {
BSTNode *test = newnode(1);
test->left=newnode(2);
test->right=newnode(3);
test->left->left=newnode(2);
test->right->right=newnode(5);
print(test);
if (assist(test))
cout << "There is duplicated" << endl;
else
cout << "There is no duplicated" << endl;
return 0;
}
Your checking function should look like this:
bool checking(BSTNode* parent, int val) {
if(parent == nullptr) // point 1
return false;
if (val == parent->data){ // point 2
return true;
}
else{
bool left = checking(parent->left, val);
bool right = checking(parent->right, val);
return left||right;
}
}
Your assist function should look something like this:
bool assist(BSTNode* parent) {
if (parent != nullptr) {
if(checking(parent->left, parent->data)) return true; // point 3
if(checking(parent->right, parent->data)) return true;
return assist(parent->left)||assist(parent->right); // point 4
}
else return false;
}
You need to check for null values.
If val is same, why are you still checking? Just stop
You need to check node's value in the left and right subtree.
Recurse it for the child nodes
If you want to check that parent value is different than child values, you might do:
bool checking(const BSTNode* node, int parent_value) {
if (node == nullptr) { return false; }
if (node->data == parent_value) { return true; }
return checking(node->left, node->data)
|| checking(node->right, node->data);
}
bool assist(const BSTNode* parent) {
if (parent == nullptr) {
return false;
}
return checking(parent->left, parent->data)
|| checking(parent->right, parent->data);
}
You could just go through the BST breadth wise with a Deque. Store the values in a set and check if the value is already in the set, if it is return true otherwise wait for the loop to finish and return true. This had the benefit of hash table lookup for values at thr cost of extra storage in O(n) time. Its also easier to follow in my opinion as it's not recursion.
bool hasDuplicate(BSTNode *parent)
{
if (!parent) return false;
std::dueue<BSTNode*> nodes;
std::unordered_set<int> vals;
nodes.push_back(parent);
while(!nodes.empty()) {
BSTNode *node = nodes.pop_front();
int v = nodes->val;
// Check if value exists and return true
if(vals.find(v) != vals.end()) return true;
// Otherwise insert it
vals.insert(v);
// insert left node if exists
if (node->left) nodes.push_back(node->left);
// insert right node if exists
if (node->right) nodes.push_back(node->right);
}
// no dups found
return false;
}
Sorry for bad indents. Did this on phone lol.

How would I count the comparisons made in a Binary Search Tree?

I was wondering how I would add a counter that represents the number of comparisons in my BST. I added a counter but my printTree function for some reason I keep getting 0 for the count. Am I suppose to count the number of comparisons made in the print function? Or should I have a separate function specifically for counting the number of comparisons made?
#include <iostream>
#include <cstdlib>
#include <fstream>
using namespace std;
struct node
{
int data;
node* left;
node* right;
};
node* root = NULL;
node* createLeaf(int data)
{
node* n = new node;
n->data = data;
n->left = NULL;
n->right = NULL;
return n;
}
void addLeaf(node* &curr, int data)
{
//If curr = NULL then add node
if(curr == NULL)
{
curr = createLeaf(data);
}
//Left(Less than)
else if(data <= curr->data)
{
addLeaf (curr->left, data);
}
//Right(greater than)
else if(data >= curr->data)
{
addLeaf(curr->right, data);
}
}
int printTree(node* Ptr, ofstream& NewData, int count)
{
//Check if tree is empty
if(root != NULL)
{
return count++;
if(Ptr->left != NULL)
{
printTree(Ptr->left, NewData, count);
}
NewData << Ptr->data; //Store Data in output file
NewData << endl;
cout << Ptr->data << " ";
if(Ptr->right != NULL)
{
printTree(Ptr->right, NewData, count);
}
}
else
{
cout << "The Tree is empty\n";
}
return Ptr->data;
}
int main()
{
ifstream dataFile;
dataFile.open("Data.txt.");
int temp, count;
count = 0;
while(dataFile)
{
dataFile >> temp;
addLeaf(root, temp);
}
dataFile.close();
ofstream NewData;
NewData.open("NewData.txt");
count = printTree(root, NewData, count);
cout << "count:" << count;
NewData.close();
system("PAUSE");
return 0;
}
Simply pass the count variable by reference (Or use a pointer. Example uses pass by reference) and then increment without returning and this will give you a simple way of counting the number of comparisons. Edited snippets of your code are below.
Note: For future reference post incrementing value to be returned will do nothing if it is being returned. e.g. use return ++count; instead of return count++;. This is why you where getting zero as the value of your count variable. A simple way of explaining this behavior is that when you return a post-incremented value it returns the value and exists that function before incrementing it. Although from what I understand of the code you did not really want to be returning the count variable.
int printTree(node* Ptr, ofstream& NewData, int &count)
{ // ^ The & specifies that is to be passed
// by reference.
//Check if tree is empty
if(root != NULL)
{
// No longer returns instead just increments.
count++;
// Your code here.
}
// Your code here.
}
int main()
{
int count = 0;
// The rest of your code here ....
// Stores the return value from print tree root "ptr->data"
int data = 0;
// New caller will modify count as it is passed by reference, but will "return ptr->data;"
data = printTree(root, NewData, count);
cout << "count:" << count;
system("PAUSE");
return 0;
}
I'd do it by defining a tiny class that was devoted primarily to counting comparisons:
template <class T>
struct holder {
static int count;
T t;
holder(T T) : t(t) {}
operator T() const { return t; }
operator <(T const &r) { ++count; return t < r.t; }
};
int holder::count = 0;
Then a node would hold instances of these instead of holding ints directly:
struct node {
holder<int> data;
node *left;
node *right;
};
Do your work with your tree, and when you want to know the number of comparisons you've done so far, look at holder<int>::count; to get it.

Finding the minimum number in a Binary Tree recursively

This is how my code looks
int main() {
//root is the rootnode of the tree
if(root!==NULL) {
int mini = min(root, root->data);
printf("minimum number is %d", mini);
}
return 0;
}
int min(node *root, int mini) {
if(root == NULL) {
return;
}
min(root->left, mini);
min(root->right, mini);
if(mini > root->data) {
mini = root->data;
}
return mini;
}
It doesn't give me the minimum number in the tree. Rather, it prints the root node as the minimum.
You need to use the results of the recursive calls instead of throwing them away.
They are supposed to be the minimum values of the subtrees.
The minimum value in a tree is the minimum of
The root value
The value in the left subtree, if there is one
The value in the right subtree, if there is one
Like this:
int min(node *root)
{
int least = root->data;
if (root->left != NULL)
{
least = std::min(least, min(root->left));
}
if (root->right != NULL)
{
least = std::min(least, min(root->right));
}
return least;
}
Try this:
int min(node *root, int mini) {
if(root == NULL) {
return -1;
}
int a;
a=min(root->left, mini);
if(a<mini)
mini=a;
a=min(root->right, mini);
if(a<mini)
mini=a;
if(root->data<mini)
mini = root->data;
return mini;
}
This works for me. Not discarding the return value.
int main() {
//root is the rootnode of the tree
if(root!==NULL) {
int mini = min(root, root->data);
printf("minimum number is %d", mini);
}
return 0;
}
int min(node *root, int mini) {
if(root == NULL) {
return;
}
mini = min(root->left, mini);
mini = min(root->right, mini);
if(mini > root->data) {
mini = root->data;
}
return mini;
}

How to check if a binary tree remains AVL and maintain it?

I'm having some trouble with the creation of an AVL tree structure in C++ for a university project. So far, I managed to make simple add and delete functions, but here comes the problem! I 've seen some codes here where the checks are made in the add function directly, but I didn't want to copy the code. Is there a way to create a seperate function which does exactly this work? The thing I can't make work is how to make the program understand in which rotation case I have to go.
My code so far is this:
struct node
{
unsigned int target;
struct node *left;
struct node *right;
};
int ClassInvertedIndex::Height(struct node *toCheck)
{
int left, right;
if(toCheck == NULL)
return 0;
left = Height(toCheck->left);
right = Height(toCheck->right);
if(left > right)
return left+1;
else
return right+1;
}
void ClassInvertedIndex::maintainAVL(struct node *toCheck)
{
if(Height(toCheck->left)-Height(toCheck->right) == 2); //Left subtree problem.
if(Height(toCheck->right)-Height(toCheck->left) == 2); //Right subtree problem.
}
bool ClassInvertedIndex::addNode(unsigned int x)
{
return insideAdd(data, x);
}
bool ClassInvertedIndex::insideAdd(struct node *toAdd, unsigned int x)
{
if(toAdd == NULL)
{
toAdd = new struct node;
if(toAdd == NULL)
{
cout << "Could not allocate memory.";
return false;
}
toAdd->left = NULL;
toAdd->right = NULL;
toAdd->target = x;
return true;
}
else if(x < toAdd->target)
{
bool result;
result = insideAdd(toAdd->left, x);
if(result)
{
//maintainAVL(toAdd);
}
return result;
}
else if(x > toAdd->target)
{
bool result;
result = insideAdd(toAdd->right, x);
if(result)
{
//maintainAVL(toAdd);
}
return result;
}
else //x already exists.
{
return false;
}
}
So, in the maintainAVL method, what should I do to decide what rotation I need?

B-tree recursive search C++

This function recursively calls itself to search the Btree and returns true if the value is found, and false if it is not found. I also want it to cout "not found" one time at the end if it is not found. It works fine except that it says "not found" numerous times (everytime it goes down a level it says not found) since it calls itself.
bool lookup(int val, btnode *n) //returns true/false if value is in btree
{
if (n==NULL) return false; //empty tree
for (int i=0;i< n->count;i++) //check in present node for the val
if(n->value[i]==val)
{
flag = true;
return true;
}
//check in child node
for(int i =0;i<n->count;i++) //check for child node
{ if(val < n->value[i])
{ cout<<"checking a different node."<<endl;
lookup(val,n->child[i]);
}
}
if(val > n->value[(n->count)-1])
{
cout<<"searching a right subtree"<<endl;
lookup(val, n->child[n->count]);
}
if (flag==false)
return false;
else return true;
}
bool lookup2(int val, btnode *n)
{
if(lookup(val, n)==false)
{
cout<<"not found"<<endl;
return false;
}
else
{
cout<<"Found it"<<endl;
return true;
}
}
You probably want to make an auxiliary method that calls this lookup function, and does the printing. Something like:
bool lookup_print(int val, btnode *n) {
bool found = lookup(val, n);
if (found) {
cout << "Found it!" << endl;
} else {
cout << "Not found..." << endl;
}
return found;
}
Also, you need to make sure that your recursive calls are returning their values if they do find a node. So everywhere you recurse, you'll want something like:
bool found = lookup(val,n->child[i]);
if (found) {
return found;
}