Compilation errors in resolving public functions in C++ - c++

I'm trying a classic programming interview problem. The idea is to create a balanced binary tree(or a tree with minimum height) from a sorted array. This is my node class.
class node{
public:
node(int data):value(data), left(nullptr), right(nullptr){}
node* sortedArrayToBinaryTree(int arr[], int start, int end){
if(start > end) return nullptr;
int mid = (start + end)/2;
node* p = new node(arr[mid]);
p->left = sortedArrayToBinaryTree(arr, start, mid-1);
p->right = sortedArrayToBinaryTree(arr, mid+1, end);
return p;
}
void preorder(node* root){
if(root == nullptr) return;
std::cout<<root->value<<" "<<std::endl;
preorder(root->left);
preorder(root->right);
}
private:
int value;
node* left;
node* right;
};
I'm reasonably sure that my logic is ok. However the issue is when I write a client code to test the functionality my public methods in node class are not being resolved.
int main() {
int arr[] = {2,7,9,13,19,21};
node* root = sortedArrayToBinaryTree();
preorder();
return 0;
}
I get the following compilation error.
error: use of undeclared identifier 'sortedArrayToBinaryTree'
node* root = sortedArrayToBinaryTree(arr, 0, 5);
^
main.cpp:10:5: error: use of undeclared identifier 'preorder'
preorder();
^
2 errors generated.

You forgot not only to pass actual arguments to the functions, but the fact, that these non-static member functions (methods) need a class instance to be called on. I don't see any.
Nevertheless, it doesn't make sense to make sortedArrayToBinaryTree and preorder members of node. If you're making a tree, there should be class tree that takes care of the sorting/ordering etc... So, logic is not OK.

Function sortedArrayToBinaryTree is a non-static member function of class node.
It may not be called withput an object of this class.
You could declare it as a static data member in the class definition
static node* sortedArrayToBinaryTree(int arr[], int start, int end){
//...
and in this case you could write
node* root = node::sortedArrayToBinaryTree( /* arguments */ );
And as the function does not have default arguments you have to specify them explicitly.
The same is applied to funcion preorder.
Take into account that these functions do not use data members of the class. So the class design is wrong.
I think you should declare these functions as static member functions of the class.

You are getting compiler errors since the functions sortedArrayToBinaryTree and preorder are declared in node as member functions and you are using them from main as though they are non-member functions.
I can think of the following ways you can resolve the problem.
Make the functions non-member functions
Declare the functions.
node* sortedArrayToBinaryTree(int arr[], int start, int end);
void preorder(node* root);
Make them friends of node.
class node{
public:
node(int data):value(data), left(nullptr), right(nullptr){}
friend node* sortedArrayToBinaryTree(int arr[], int start, int end);
friend void preorder(node* root);
private:
int value;
node* left;
node* right;
};
And then use them from main, with right arguments.
int main() {
int arr[] = {2,7,9,13,19,21};
node* root = sortedArrayToBinaryTree(arr, 0, sizeof(arr)/sizeof(arr[0]));
preorder(root);
return 0;
}
Make the functions static member functions
class node{
public:
node(int data):value(data), left(nullptr), right(nullptr){}
static node* sortedArrayToBinaryTree(int arr[], int start, int end);
static void preorder(node* root);
private:
int value;
node* left;
node* right;
};
and call them from main.
int main() {
int arr[] = {2,7,9,13,19,21};
node* root = node::sortedArrayToBinaryTree(arr, 0, sizeof(arr)/sizeof(arr[0]));
node::preorder(root);
return 0;
}

Related

How to get rid of these compiler warnings?

When I run my code with the below implementation of the Constructor of LRUCache class, I get 12 compiler warnings as follows:
The same set of first six warnings is repeated again.
struct Node{
Node* next;
Node* prev;
int value;
int key;
Node(Node* p, Node* n, int k, int val):prev(p),next(n),key(k),value(val){};
Node(int k, int val):prev(NULL),next(NULL),key(k),value(val){};
};
class Cache{
protected:
map<int,Node*> mp; //map the key to the node in the linked list
int cp; //capacity
Node* tail; // double linked list tail pointer
Node* head; // double linked list head pointer
virtual void set(int, int) = 0; //set function
virtual int get(int) = 0; //get function
};
class LRUCache : public Cache
{
private:
int count;
public:
LRUCache(int capacity)
{
cp = capacity;
tail = NULL;
head = NULL;
count = 0;
}
What is wrong with my code?? What should be the proper code implementation so as not to get any warnings??
The problem here is initialization order in your Node struct.
In C++ members are initialized in the order they are declared, regardless the order they are listed in the constructor initializer list.
Thus they are initialized in the order next, prev, value, key.
Listing them differently in the constructor can be misleading and thus the warning is telling you to list them there in the same order they are declared.

Tree not being created

When I call the function createBst(), the program gets terminated in the function.
I put a print statement after the function but it is not called.The next print statement "terminated" is not called
int main(){
bst b;
b.createBst();
std::cout<<"terminated"<<std::endl;
return 0;
}
class node{
public:
int val;
node* left;
node* right;
};
class bst{
public:
node* head;
void createBst();
node* newNode(int val);
};
node* bst::newNode(int v){
node n1;
node* n=&n1;
n->val=v;
n->left=nullptr;
n->right=nullptr;
return n;
}
void bst::createBst(){
head=bst::newNode(10);
head->left=bst::newNode(11);
(head->left)->left=bst::newNode(7);
head->right=bst::newNode(9);
(head->right)->left=bst::newNode(15);
(head->right)->right=bst::newNode(8);
}
the output should be "terminated".
For starters the classes shall be defined before their usage in main.
This function
node* bst::newNode(int v){
node n1;
node* n=&n1;
n->val=v;
n->left=nullptr;
n->right=nullptr;
return n;
}
invokes undefined behavior because it returns pointer ro a local variable n1 that will not be alive after exiting the function.
The function could be defined the following way
node* bst::newNode(int v)
{
return new node { v, nullptr, nullptr };
}
In fact the function can be a private static member function
class bst{
public:
node* head;
void createBst();
private:
static node* newNode(int val);
};
And the class node should be a nested private (or protected) class of the class bst.
Also you need either a default constructor for the class bst that will initialize head to nullptr or you have to explicitly initialize head to nullptr in the class definition like
class bst{
public:
node* head = nullptr;
void createBst();
private:
static node* newNode(int val);
};
To insert a data into the tree you should write a function for example like this
void insert( int value )
{
node **current = &head;
while ( *current != nullptr )
{
if ( value < ( *current )->val )
{
current = &( *current )->left;
}
else
{
current = &( *current )->right;
}
}
*current = newNode( value );
}

Passing a linked list to a function and making sure it is not modified

Is there a way to pass a linked list to a function and ensuring that it is not modified?
We can pass a const head pointer to a function, and this will make sure that the head is not modified. However, the function could access other nodes from head and modify those.
May be you want to try something like this:
class Node{
private:
Node* _next;
public:
Node(Node* next) : _next(next){}
Node* getNext(){ return _next; }
const Node* getNext() const {return _next; }
};
p.s. IMHO. C++ prorammers very often ignore references and use pointers in places they not needed. May that be an option for your case? :)
struct Node{ Node& _next; Node(Node& next) : _next(next){} };
PP.SS. The second getNext may be not needed in your concrete case. It is just to make the life easier if you have functions taking const node pointers. In the example below I will try to clear the idea with const-method a bit more :
#include <iostream>
#include <cstdlib>
class Node{
private:
Node* _next;
public:
Node(Node* next) : _next(next){}
Node* getNext(){ std::cout << "getNext\n"; return _next; }
const Node * getNext() const { std::cout << "getNext const\n"; return _next; }
};
void f1(Node* node){ node->getNext(); }
void f2(const Node* node){ node->getNext(); }
int main() {
Node* n1 = new Node(NULL);
Node* n2 = new Node(n1);
f1(n2);
f2(n2);
}
if you want to traverse through the linkedList Without changing it,
just overload your traversal functions with constant ones.

C++ Header and Declaration Nested struct and class syntax

So I'm trying to define a header file and declaration file with the appropriate code. In my class I am using a struct and then using the structs members to initialize other functions. I am not sure how to do the pathing to link the class and struct to the appropriate function and was hoping someone could help.
This is my header file here.
class AVL {
public:
struct node {
int data;
node* left;
node* right;
int height;
};
node* root;
node* insert(int key, node* tree);
node* oneright(node*& tree);
node* oneleft(node*& tree);
node* twoleft(node*& tree);
node* tworight(node*& tree);
int height(node* tree);
int getBalance(node* tree);
int preorder(node* tree);
AVL();
node* insert(int key);
void parsetree();
vector<int> vvector;
vector<int> hvector;
vector<int> bfvector;
};
The main problem I am having is how to declare it in the .cpp file
here
For example, if I wanted to do insert function how would I properly do the syntax. For that I have
node* AVL::node::insert(int key, node* tree)
But that is throwing me an error and I haven't been able to find anything when searching for it. Thank you!
In AVL.h
class AVL {
node* root;
node* insert(int key, node* root);
node* insert(int key);
};
in AVL.cpp
AVL::node* AVL::insert(int key, AVL::node* root) {
//code here...
}
AVL::node* AVL::insert(int key) {
//code here...
}
As it is mention in one the comments, the insert is not a member of the node struct.

Program throws error when I increment a private static variable in C++

I created a private static variable that keeps track of the number of elements in the linked list.
struct node
{
int data;
node *next;
};
class linkedList
{
private:
node *head,*tail;
static int listSize;
public:
linkedList()
{
head=NULL;
tail=NULL;
}
void insert(int n)
{
node *temp=new node;
temp->data=n;
temp->next=NULL;
if(head == NULL)
{
head=temp;
tail=temp;
}
else
{
tail->next=temp;
tail=temp;
}
linkedList::listSize+=1;
}
};
void main()
{
linkedList l;
l.insert(10);
l.insert(20);
}
The compiler throws an error when it reaches the line linkedList::listSize+=1;
error: ‘linkedList’ has not been declared.
Once your typos corrected (inser(20) instead of insert(20) and : instead of ; in linkedList(), your program almost compiles.
There is just one thing missing: you need to implement the listSize variable somewhere for example by putting int linkedList::listSize; before main:
...
int linkedList::listSize; /(/ <<< add this
void main()
{
linkedList l;
l.insert(10);
l.insert(20);
}
But why are you using a static variable for counting the elements of the list? You probably want listSize to be an ordinary (non static) class member, just as head and tail:
class linkedList
{
private:
node * head, *tail;
int listSize; // no static
public:
...
and drop the int linkedList::listSize; suggested before.