I am writing a code to return data of a node in BST based on id.
below is my node class:
struct Node{
int id;
string data;
Node *left;
Node *right;
Node();
};
below is my node constructor: I defined id and data in addNode function
Node :: Node(){
this->left = nullptr;
this->right = nullptr;
}
below is my BST class:
class BST{
private:
Node * root = nullptr;
void setRoot(Node *);
Node* getRoot();
public:
Node *addNode(BST *, int);//helper function
Node *addNode(Node *,int);
string getEntry(BST*,int);//helper function
string getEntry(Node*,int);
}
below is my helper functions:
Node *BST::addNode(BST *bst, int val){
addNode(bst->getRoot(),val);
}
string BST::getEntry(BST* bst,int id){
getEntry(bst->getRoot(),id);
}
below is my addNode class:
Node* BST::addNode(Node* root, int val) {
Node *newNode = new Node();
newNode->id = val;
newNode->data = "Number " + to_string(val);
if (root == nullptr) {
if (getRoot() == nullptr){
setRoot(newNode);
}
setCount(getCount()+1);
return newNode;
}
if (root->id > val) {
root->left = addNode(root->left, val);
} else {
root->right = addNode(root->right, val);
}
return root;
}
below is my getEntry class:
string BST::getEntry(Node *base,int id) {
if (base == nullptr){
return "";
}
if (base->id == id){
cout<<base->data<<endl;
return base->data;
}
getEntry(base->left,id);
getEntry(base->right,id);
}
below are the nodes I passed in from main:
int main(){
BST *newBst = new BST();
newBst->addNode(newBst,1);
newBst->addNode(newBst,2);
newBst->addNode(newBst,3);
newBst->addNode(newBst,2);
newBst->addNode(newBst,3);
newBst->addNode(newBst,5);
newBst->addNode(newBst,7);
newBst->addNode(newBst,10);
cout<<newBst->getEntry(newBst,5)<<endl;
return 0;
}
The code would compile but does not return anything, I tried to debug, at the "return base->data statement", there is an error "can not access memory at address 0xc8". What causes the problem and what can I do about it?
this is the warning I got when I debug the code.
if (base->id != id){
getEntry(base->left,id);
getEntry(base->right,id);
}
As you are using a sorted tree, you know which of the right or left node you need to have a look at. Also, you need to return something:
if (base->id > val){
return getEntry(base->left,id);
}
return getEntry(base->right,id);
But the design with addNode is very bad, you shouldn't have to pass the root twice!
Related
I am working on a BST and when I print out the elements in any order, I get a random '0' appended to it, but I cannot find where its coming from.
I followed the pseudo code thats present in Introduction to algorithms by Cormen and have also looked at Geeks for Geeks but I have no luck getting rid of that 0.
#include <iostream>
using namespace std;
class Node {
public:
int data;
Node* LeftChild;
Node* RightChild;
Node(int data){
this->data = data;
this->LeftChild = NULL;
this->RightChild = NULL;
}
//pointers of the class
};
class BST {
private:
Node* root;
public:
BST(){ ///creating an empty tree in Constant Time
root = new Node(NULL);
}
Node* getRoot(){ return this->root; };
int i =0;
void printTree(Node *root)
{
if (root == NULL)
return;
else {
printTree(root->LeftChild);
cout << root->data << " ";
printTree(root->RightChild);
}
}
Node* InsertNode(Node *root,int data)
{
Node *z = new Node(data);
Node *y = new Node(NULL);
Node *x = this->root;
//if(x->data < z->data){
// x = z;
//return x;
//}
while(x!= NULL){
y = x;
if(data < x->data){
x = x->LeftChild;
}
else{
x = x->RightChild;
}
}
if(y== NULL) y= z;
else if(data < y->data){
y->LeftChild = z;
}
else{
y->RightChild =z;
}
return y;
/*
if(this->root->data== NULL){
this->root =z;
return root;
}
else{
this->root =y;
}
*/
//this->root = z;
//return root;
}
bool FindNode(Node *root,int data);
int Largest(Node *root){
return root->data;
}
};
int main()
{
BST myBst;
Node * root = (myBst.getRoot());
root = myBst.InsertNode(root, 24);
myBst.InsertNode(root, 60);
myBst.InsertNode(root, 55);
myBst.InsertNode(root, 32);
myBst.printTree(root);
return 0;
}
Here is the output:
0, 24,32,55,60
The constructor does not make a sense
BST(){ ///creating an empty tree in Constant Time
root = new Node(NULL);
}
There is created a dummy node with initialization of the data member data with NULL.
What you need is just to write
BST() : root( nullptr ) { ///creating an empty tree in Constant Time
}
The function InsertNode must have only one parameter instead of two parameters as you wrote
Node* InsertNode(Node *root,int data){
The pointer root is the data member of the class. So there is no need to pass it to the function. Otherwise the function should be declared as a static member function of the class (that nevertheless does not make a great sense).
That is the function should be declared like
void InsertNode( int data ){
Also the function has at least a memory leak
Node* InsertNode(Node *root,int data){
Node *z = new Node(data);
Node *y = new Node(NULL);
Node *x = this->root;
while(x!= NULL){
y = x;
//...
The function can be written for example the following way
void InsertNode( int data )
{
Node *new_node = Node( data );
Node **current = &root;
while ( *current != nullptr )
{
if ( data < ( *current )->data )
{
current = &( *current )->LeftChild;
}
else
{
current = &( *current )->RightChild;
}
}
*current = new_node;
}
I've created a simple recursive function that performs preorder traversal to return a node that matches a target string.
#include <bits/stdc++.h>
using namespace std;
class Node {
public:
string value;
Node *left, *right;
Node(string value) {
this->value = value;
this->left = NULL;
this->right = NULL;
}
};
class Tree {
public:
Node* preorder(Node* root, string target) {
if (root == NULL) return NULL;
if (root->value == target) {
return root;
}
preorder(root->left, target);
preorder(root->right, target);
}
};
int main() {
Node* a = new Node("a");
Node* b = new Node("b");
Node* c = new Node("c");
Node* d = new Node("d");
a->left = b;
a->right = c;
c->left = d;
Tree t = Tree();
Node* found = t.preorder(a, "d");
cout << found->value << endl;
}
The traversal is done correctly, but the program doesn't print anything. I just get a [Done] exited with code=3221225477 in 2.038 seconds after compiling with g++ and running.
Where did I mess up with the pointers?
preorder doesn't return anything in yhe recursive cases. The behaviour of the program is unrefined.
Hint for future: Use compiler warnings.
So, I started learning and reading about OOP not so long ago, I've been implementing all the data structures I know using classes and objects just for overall practice and to get comfortable with using OOP in c++.
I'm implementing the tree data structure and I've been wondering how to call a method recursively(I'm aware that I have to pass in an argument) so that when I create an object in main and call a specific method it's written like the following a.inorder(); and not a.inorder(root) since root is a private attribute.
Is this possible ?
My code:
#include<iostream>
using namespace std;
struct node
{
int data;
node* left;
node* right;
};
class tree
{
private:
node* root;
public:
tree();
tree(int val);
void insert(int val);
void preorder();
void postorder();
void inorder();
int count();
};
tree::tree() : root { NULL }
{
}
tree::tree(int val)
{
root = new node;
root->data = val;
root->left = root->right = NULL;
}
void tree::insert(int val)
{
if (!root)
{
root = new node;
root->data = val;
root->left = root->right = NULL;
}
else
{
node* t = root;
node* p = NULL;
while (t)
{
p = t;
if (val > root->data)
t = root->right;
else
t = root->left;
}
t = new node;
t->data = val;
t->left = t->right = NULL;
if (p->data > t->data)
p->left = t;
else
p->right = t;
}
}
void tree::preorder()
{
if (root)
{
}
}
In your design, a node refers to itself. Since it is the node object that is recursive, you could define the recursive method on node:
struct node
{
int data;
node* left;
node* right;
void preorder() {
//...
left->preorder();
right->preorder();
}
};
And then, tree::preorder() would just dispatch a call to root->preorder().
Write a private static recursive function passing to it the pointer to the root node and call the function from the corresponding public non-static member function.
For example
public:
std::ostream & preorder( std::ostream &os = std::cout ) const
{
return preorder( root, os );
}
//...
private:
static std::ostream & preorder( const node *root, std::ostream &os );
//...
This is a comment rather than an actual answer, as it addresses a different issue than you are asking about. However, it is too long for a comment space, that's why I post it here.
I suppose you erroneously refer to root in this part
while (t)
{
p = t;
if (val > root->data)
t = root->right;
else
t = root->left;
}
IMHO it should look like this:
while (t)
{
p = t;
if (val > t->data)
t = t->right;
else
t = t->left;
}
Also compare the code to seek a place for insert with a code that makes an actual insertion:
if (p->data > t->data)
p->left = t;
else
p->right = t;
You've put a comparison subexpressions in reversed order - when seeking, you test whether the new value is greater than that in an existing node, but when inserting, you test whether the existing value is greater than the new one. If they differ, the code will work OK, because you also swapped left and right in the 'then' and 'else' branch.
However, if the values appear equal, the execution control will go to 'else' in both places. As a result the testing code may stop at empty left pointer, but then a new node would get appended to the right, which was not tested for being NULL.
Why would the tree class do intrinsic operations on node? The node class knows best the node's internal structure, so let it initialize itself. This will also help you to stick to the DRY principle and, indirectly, to the KISS principle, as well as the Single-responsibility principle.
struct node
{
int data;
node* left;
node* right;
node(int val) : data(val), left(NULL), right(NULL) {}
};
class tree
{
private:
node* root;
public:
tree();
tree(int val);
void insert(int val);
};
tree::tree() : root { NULL }
{
}
tree::tree(int val) : root(new node(val))
{
}
void tree::insert(int val)
{
if (!root)
{
root = new node(val);
}
else
{
node* t = root;
node* p = NULL;
while (t)
{
p = t;
if (val < t->data)
t = t->left;
else
t = t->right;
}
t = new node(val);
if (t->data < p->data)
p->left = t;
else
p->right = t;
}
}
Additionally, you can make insert recursive, too.
struct node
{
int data;
node* left;
node* right;
node(int val) : data(val), left(NULL), right(NULL) {}
};
class tree
{
private:
node* root;
public:
tree();
tree(int val);
void insert(int val);
protected:
void insertat(node* p, int val);
};
void tree::insert(int val)
{
if (!root)
root = new node(val);
else
insertat(root, val);
}
void tree::insertat(node* t, int val);
{
if (val < t->data)
{
if (t->left)
insertat(t->left, val);
else
t->left = new node(val);
}
else
{
if (t->right)
insertat(t->right, val);
else
t->right = new node(val);
}
}
I am trying to build a BST in C++, the root node inside class was not affecting when in call insert() function, it remains NULL.
I am passing root to insert_tree() function when I need to insert data into the tree but when I try to print root value inside insert_tree it always returning NULL
#include <iostream>
struct node
{
int value;
node *left;
node *right;
};
class bst
{
private:
node *root;
node* insert(node* parent,int value)
{
if(parent== NULL){
parent = new node;
parent->value = value;
parent->left = parent->right = NULL;
}
else if(parent->value>value){
parent->left = insert(parent->left,value);
}
else{
parent->right=insert(parent->right,value);
}
return parent;
}
void display(node* parent){
if(parent != NULL){
display(parent->left);
std::cout << parent->value <<"\t";
display(parent->right);
}
}
public:
bst(){
root = NULL;
}
void insert(int value){
root = insert(root,value);
}
void display(){
display(root);
}
};
int main(int argc, char const *argv[])
{
bst b1;
b1.insert(10);
b1.insert(1);
b1.insert(11);
b1.insert(9);
b1.display();
return 0;
}
I would suggest you read about BST first here and learn how insertion is done in a BST. First of all the algorithm is wrong and secondly, use pass by reference in insert_tree() function instead of pass by value. As you are passing by value, so the value of root doesn't change.
I have made a function for insertion in BST using loops and it is working perfectly fine.
Now, when iam writing to do it using recursion i don't know why it's not working properly, however the logic is correct according to me. It seems that no newnode is being added to the BST tree and head of the tree after coming out of the insertion function is again becoming NULL.
#include <iostream>
using namespace std;
class node{
public:
int data;
node *right;
node *left;
node(){
data=0;
right=NULL;
left=NULL;
}
};
class tree{
node *head;
int maxheight;
void delete_tree(node *root);
public:
tree(){head=0;maxheight=-1;}
void pre_display(node* root);
node* get_head(){return head;}
void insert(int key,node* current);
};
void tree::insert(int key,node *current){
if(current==NULL)
{
node *newnode=new node;
newnode->data=key;
current=newnode;
}
else{
if(key<current->data)
insert(key,current->left);
else
insert(key,current->right);
}
return;
}
void tree::pre_display(node *root){
if(root!=NULL)
{
cout<<root->data<<" ";
pre_display(root->left);
pre_display(root->right);
}
}
int main(){
tree BST;
int arr[9]={17,9,23,5,11,21,27,20,22},i=0;
for(i=0;i<9;i++)
BST.insert(arr[i],BST.get_head());
BST.pre_display(BST.get_head());
cout<<endl;
system("pause");
return 0;
}
Please tell me what should i change in the algorithm to make it work.
In your insert function
void tree::insert(int key,node *current){
if(current==NULL)
{
node *newnode=new node;
newnode->data=key;
current=newnode;
}
else{
if(key<current->data)
insert(key,current->left);
else
insert(key,current->right);
}
return;
}
you allocate a new node but never set BST::head to newly allocated head. So BST::get_head will always return null.
One way to fix this would be for insert to return a node. This would be root node in your case and set the BST::head to this value.
Your recursion looks fine, but you don't actually add the node anywhere! You just recurse through the tree.
Edit You can change the insert method to take a pointer to a pointer, like this:
void tree::insert(int key, node **current)
{
if(*current == NULL)
{
node *newnode = new node;
newnode->data = key;
*current = newnode;
}
else
{
if(key < (*current)->data)
insert(key, &(*current)->left);
else
insert(key, &(*current)->right);
}
}
And in main call it like this:
BST.insert(arr[i], &BST.get_head()); // Note the ampersand (&)
you should try this
node tree:: insert ( int key , node * current ) {
if ( ! current ) {
node * newnode = new node ;
newnode -> key = key;
current = newnode ;
}
else if ( key < current -> key ) {
current -> left = insert ( key , current ->left
}
else
current -> right = insert ( key , current->right )
return current ;
}
it works fine....jsut update the head node every time whenver a new node is inserted and it will return the updated current node.
Just change your function as
void tree::insert(int key,node*& current){
if(current==NULL)
{
node *newnode=new node;
newnode->data=key;
current=newnode;
}
else{
if(key<current->data)
insert(key,current->left);
else
insert(key,current->right);
}
return;
}
make your input pointer as a reference parameter.
struct node{
node* left;
node* right;
int data;
};
node* root=NULL;
node* create(node* head,int val){
if(head==NULL){
node* nn=new node;
nn->data=val;
nn->left=NULL;
nn->right=NULL;
head=nn;
}
else if(val<head->data)
head->left=create(head->left,val);
else if(val>head->data)
head->right=create(head->right,val);
return head;
}
int main(){
int num=0;
cout<<"Enter value in tree or press -1 to Exit\n";
while(num!=-1){
cin>>num;
if(num==-1){
cout<<"\nTree Created\n";
break;
}
else{
root=create(root,num);
}
}
}
hope this code solves your problem
void insertNode_recursive(int value, TreeNode *current)
{
if (current == NULL)
{
if (current == NULL && isEmpty())
{
TreeNode *new_node = new TreeNode(value);
current = new_node;
root = new_node;
}
else
{
TreeNode *new_node = new TreeNode(value);
current = new_node;
}
}
else
{
if (value < current->getValue())
{
insertNode_recursive(value, current->getLeft());
}
else if (value > current->getValue())
{
insertNode_recursive(value, current->getRight());
}
else
{
cout << "\nDuplicate Value are Not Allowed\n";
}
}
}
This Code is Useful For Recursively Print the Tree Node