I am getting the above error and its pointing to my call for add(root, node). What does this error mean? I have tried moving the private add to the top but that doesnt work either. Also, it cant be because its private because its in the same class, right?
class Tree{
public:
Node *root;
Tree(Node *r){
root = r;
}
void add(Node node){
add(root, node);//error here
}
private:
void add(Node parent, Node node){
if(parent == root && root == nullptr){
root = node;
}
if(parent == nullptr){
parent(node->value, nullptr, nullptr);
}
else if(node > parent){
add(parent->right, node);
}
else {
add(parent->left, node);
}
Your function needs the signature
void add(Node* parent, Node* node)
Note that these are Node* instead of Node. The same goes for the public overload of that function
void add(Node* node)
This is apparent because 1) you are doing comparisons to nullptr and 2) you keep dereferencing your variables with -> instead of .
CoryKramer has spotted some errors, I'll add this also.
you can't compare pointers so it should be data:
else if(node->value > parent->value){
add(parent->right, node);
Related
#include<iostream>
using namespace std;
struct node{
int data;
node *left;
node *right;
node(int value = 0);
};
node::node(int value){
data = value;
left = NULL;
right = NULL;
}
class LinkedList{
public:
node *root;
LinkedList();
bool isEmpty();
void insertInto(int value, node *key);
};
LinkedList::LinkedList(){
root = NULL;
}
bool LinkedList::isEmpty(){
if(root == NULL) return true;
}
void LinkedList::insertInto(int value, node* root){
if (root == NULL)
{
node *n = new node(value);
root = n;
}
else if(value <= root->data){
insertInto(value, root->left);
}
else if(value > root->data){
insertInto(value,root->right);
}
}
int main() {
cout<<"I am gonna write the insertion of a binary tree"<<"\n";
LinkedList sample;
if(sample.isEmpty()) cout<<"THe tree is empty"<<endl; else cout<<"The tree is NOT empty"<<endl;
sample.insertInto(5,sample.root);
if(sample.isEmpty()) cout<<"THe tree is empty"<<endl; else cout<<"The tree is NOT empty"<<endl;
return 1;
}
I have been working on this for quite some time, I dont seem to understand why the result is showing that the tree is empty even after adding the value 5. ALso please give tips on how I can improve. Thanks
Ignoring the comments that I could make about the style/structure of the code you've posted:
void LinkedList::insertInto(int value, node* root){
if (root == NULL)
{
node *n = new node(value);
root = n;
}
You're not passing the node* root variable by reference here. Instead, you're changing a copy of the node* root to point to the new node object you constructed. If you want this code to actually change the value of the sample.root variable that you passed in from the main, you must pass root by reference.
void LinkedList::insertInto(int value, node* &root){
Since LinkedList::insertInto is a member function anyway, why pass in root at all?
You have access to the member variable root, just use that instead. If you still want to be able to use it recursively, you could make a public function with just the value, and have that call a private version that also takes in a node* is a parameter.
Here are some coding style suggestions, since you asked for them:
Best coding practice dictates that you make member variables of your class private, and use public member functions to manipulate your class instead. This is for a variety of different reasons. One explanation is here:
https://softwareengineering.stackexchange.com/questions/143736/why-do-we-need-private-variables
So your class (and let's call it BinaryTree instead), would look something like this:
class BinaryTree{
public:
/* functions */
private:
node *root;
};
So instead of making the user of the class provide the root of the BinaryTree (which doesn't make sense since we know it anyway), we just ask them for the value to insert, and provide the root ourselves.
class BinaryTree{
public:
/* other functions */
void insertInto(int value);
private:
void insertInto(int value, node* &n);
node *root;
};
// Public version of the insertInto function
void insertInto(int value) {
insertInto(value, root);
}
// Private helper function for insertInto
void insertInto(int value, node* &n) {
if (n == NULL)
{
n = new node(value);
}
else if(value <= root->data){
insertInto(value, root->left);
}
else if(value > root->data){
insertInto(value,root->right);
}
}
int main() {
BinaryTree sample;
sample.insertInto(5);
}
I have the following code to insert in the bst however, it fails to insert all the nodes except for the root. Any idea what I am doing wrong?
class Node
{
public:
int data;
Node* right;
Node* left;
Node(int data)
{
this->data = data;
}
Node() {}
};
class BST
{
public:
Node* head;
void insert(int data)
{
if (head == nullptr)
{
head = new Node(data);
head->data = data;
}
else
{
// head = new Node(data);
insertNode(data, head);
}
}
void insertNode(int data, Node* head)
{
if (head == nullptr)
{
head = new Node(data);
return;
}
if (head)
{
Node* temp = head;
if (temp->data > data)
{
insertNode(data, temp->left);
}
else if (temp->data <= data)
insertNode(data, temp->right);
}
}
};
The parameter head in insertNode shadows the member variable named head.
However, while that's a really bad practice, the other answer is the true reason for your error, so please select his answer instead (once you get it working, of course).
I'd recommend changing the signature of insertNode to
void insertNode(int data, Node*& node)
Also, you don't need to check for head == nullptr in insert. You have a duplicate check in insertNode
So insert could look like this:
void insert(data) {
insertNode(data, head);
}
Finally, you're not initializing head within the constructor. It's possible that head will be initialized to something other than nullptr, especially if you compile this in release mode. Add a constructor like this:
BST() : head(nullptr) {
// Other init stuff here if necessary
}
You'll also want to make Node* head a private data member instead of public.
insertNode() takes a copy of the pointer, so changes made inside the function have no effect on the actual pointer in the tree. What you want to do is take a reference to the pointer:
void insertNode(int data, Node*& head)
In your function " insertNode" you are using if(head) , this if will work only if head == 1 , and head is never equals to 1 because its a pointer , so this "if" is not working.!
Let's say i have unbalanced binary tree data structure. After init() i have variable Node* root set to NULL
One of my method is trying to insert node in the tree
bool insertNode(Node ** currentNode, const string & key, int val)
{
Node* newNode;
if (*currentNode == NULL)
{
newNode = newNode(key,val);
*currentNode = newNode;
if(root==NULL) root = newNode;
return true;
}
if (key<*currentNode->getKey())
{
insertNode((Node **)&(*currentNode)->getLeft(), key, val); //error
}
if (key>*currentNode->getKey())
{
insertNode((Node **)&(*currentNode)->getRight(), key, val); //error
}
return false;
}
Node* getRoot() { return root; }
It is called
insertNode((Node **)&(tree.getRoot())); //error
Unfortunatelly compiler gives me errors
error: lvalue required as unary ‘&’ operand|
If i call fce insertNode with variable Node* node like this
Node* node = tree.getRoot();
insertNode((Node **)&node); //no error
It's without error.
Could you please explain me why?
EDIT:
After ravi's answer i realised that i've changed only copies of addresses.
To solve it i changed fce
Node** getRoot() { return &root; }
Also member methods for Node
Node** getLeft()
{
return &m_left;
}
Node** getRight()
{
return &m_right;
}
insertNode((Node **)&(tree.getRoot()));
This is because you cannot use return values of function returning built in types by value as an l-value.
output: Access violation reading location 0x0093F3DC.
i cant seem to figure out the problem. the head and next pointers are initialized with null in respective constructors.
class List{
public:
node *head;
List(void) // Constructor
{
head = NULL;
}
void insertNode(int f)
{
node *newNode;
newNode=new node();
newNode->value = f;
newNode->next=head;
head=newNode;
}
void displayList()
{
node *ptr=head;
while (ptr!=NULL)
{
cout<<ptr->value<<endl;
ptr=ptr->next;
}
}
bool search( int val)
{
node *ptr= head;
while (ptr!=NULL)
{
if(ptr->value == val)
{
return true;
}
ptr=ptr->next;
}
return false;
}
};
Most likely, it is better to declare only a pointer, instead of allocating a Node instance then wiping out the newly allocated memory (e.g. causing a dangling memory leak). For example:
bool search( int val)
{
//
// Declare the pointer to traverse the data container, assign to the head
// This works only if head is valid. It is assumed that head is pointing
// to valid memory by the constructor and/or other class member functions.
//
node *ptr = this->head;
while (ptr!=NULL)
{
if(ptr->value == val)
{
return true;
}
ptr=ptr->next;
}
return false;
}
In the class implementation details above, the internal head pointer is always assigned to the newNode memory inside InsertNode. Consequently head moves every time InsertNode is called. Is this the desired functionality?
I'm building my own linked list class and I'm having some issues figuring out how to write some functions to help me traverse this list. This is my first time building a linked list from scratch, so if my approach is unconventional please let me know what might be more conventional.
I'd like write a function, within the List class that allows me to increment to the next element called getNext() as well as one that getPrev();
I wrote getNext like this:
T* getNext(){return next;}
However it tells me next is not declared within the scope. I'd also like to write a function that lets me access and modify the object within the list. I was considering using the bracket operator, but first I need to write a function to return the data member. Perhaps If I take a similar approach as I did within my pop functions.. thinking about it now. However, I'd still appreciate any advice.
Here is my List class:
#ifndef LIST_H
#define LIST_H
//List Class
template <class T>
class List{
struct Node {
T data;
Node *next;
Node *prev;
//Constructs Node Element
Node(T t, Node* p, Node* n) { data = (t); prev = (p); next = (n); }
// T *getNext() {return next;}
};
Node *head;
Node *tail;
public:
//Constructor
List() { head = NULL; tail=NULL; }
//Destructor
~List() {
while(head){
Node * temp(head);
head = head->next;
delete temp;
}
}
//is empty
bool empty() const {return (!head || !tail ); }
operator bool() const {return !empty(); }
//Push back
void push_back(T data) {
tail = new Node(data, tail, NULL);
if(tail->prev) //if the node in front of tail is initilized
tail->prev->next = tail;
if( empty() )
head = tail;
}
//Push front
void push_front(T data) {
head = new Node(data, NULL, head);
if(head->next)//if the node following head is initilized
head->next->prev = head;
if( empty() )
tail = head;
};
T pop_back() {
if( empty() )
throw("Error in List: List is empty\n");
Node* temp(tail);
T data(tail->data);
tail = tail->prev;
if( tail )
tail->next = NULL;
else
head = NULL;
delete temp;
return data;
}
T pop_front() {
if (empty())
throw("Error in List: List is empty\n");
Node* temp(head);
T data(head->data);
head = head->next;
if(head)
head->prev=NULL;
else
tail = NULL;
delete temp;
return data;
}
T getNext(){return next;}
};
#endif
getNext should be part of the struct Node and return a Node*
Node* getNext() { return next; }
Then from that you can get the value.
If you have to have it part of the list itself, which I would not recommend it will need to take a parameter of what Node you would like the next of:
Node* getNext(Node* n) {return n->next;}
Again, I recommend the first option.
Here is an approximate whole class with both of these:
template<typename T>
class List {
public:
struct Node {
Node* next, prev;
T data;
//some constructor and stuff
Node* Next() {return next;}
}
//some constructors and other functions
Node* getNext(Node* _n) {return _n->Next();}
}
then to use:
int main() {
List<int> l;
//add some stuff to the list
//get the head of the list
List<int>::Node* head = l.head; //or some corresponding function
//then
List<int>::Node* next = head->Next();
//or
List<int>::Node* next2 = l.getNext(head);
}
for starters getNext() should not return a pointer to the template class, it should return a pointer to the Node structure.
So it should be
Node* getNext(){return next;}
Because it's a member of Node struct and getNext is member of List. You should access it from an object of type Node.