I want to implement single linked list with a header class but i am also trying making information and pointer of linked list private and compiler says me
lvalue required as left operand of assignment
pred->Next()=temp->Next();
What's the wrong with this code?
#include <iostream>
using namespace std;
class IntSLLNode{
private:
int info;
IntSLLNode * next;
public:
IntSLLNode(){
next=0;
}
IntSLLNode(int el,IntSLLNode *ptr=0){
info=el;
next=ptr;
}
int Info(){return info;}
IntSLLNode * Next(){return next;}
};
IntSLLNode * head,* tail;//header structure
class IntSLList{
IntSLList(){
head=0; tail=0;
}
public:
void addToHead(const int&);
void addToTail(const int &);
int deleteFromHead();
int deleteFromTail();
void deleteNode(int&);
void listele();
};
void IntSLList::addToHead(const int &el){
head=new IntSLLNode(el,head);
if(tail==0)
tail=head;
}
void IntSLList::addToTail(const int &el){
if(tail==0){
head=tail=new IntSLLNode(el,head);
}
else{
tail->Next()=new IntSLLNode(el);
tail=tail->Next();
}
}
int IntSLList::deleteFromHead(){
if(head==0){
cout<<"No value such that";
return -1;
}
int el=head->Info();
IntSLLNode * temp=head;
if(head==tail){
head=tail=0;
}
else{
head=head->Next();
}
delete temp;
return el;
}
First of all, you need to understand the difference between lvalue and rvalue. In simple words, lvalue is something that can be assigned (variable etc.) while rvalue is a temporary value (just like the one that you are returning here: IntSLLNode * Next(){return next;})
Then, by trying to assign something to rvalue, you get an error.
As a solution here, you could make your IntSLLNode * next; public or return a reference to this class member in your Next() function.
Assignment to a return value of a function/method would not do anything useful. You can only assign to a reference of a value returned by a function.
class IntSLLNode{
...
int& Info(){return info;}
IntSLLNode*& Next(){return next;}
};
But then, it would break encapsulation of that node and would allow any external code to change the linking of your nodes in the list by mistake. Personally I would hide the whole node class into the list class and provide methods to access Info() values to code outside this file.
Related
So I am trying to implement a Stack using a linked list and classes. Right now I have 6 different files: node.h, node.cpp, LL.h, LL.cpp, Stack.h, and Stack.cpp. I want to complete the Stack.h and Stack.cpp files so that they work as they should. I already implemented the linked list functions and they work as they should. Here is the code:
node.h :
// node.h
class node { // node class used in the LL (linked list) class
private:
node * next; // Pointer to next node of an LL
int data; // integer data stored in this node
public:
node(int x, node * n); // Constructor
~node(); // Destructor
void set_data(int x); // Change the data of this node
void set_next(node * n);// Change the next pointer of this node
int get_data(); // Access the data of this node
node * get_next(); // Access the next pointer of this node
};
LL.h :
// LL.h
#include "node.h"
// Linked list class, used in the Stack class
class LL {
private:
node * head; // pointer to first node
node * tail; // pointer to last node
public:
LL(); // Constructor
~LL(); // Destructor
void prepend(int value); // add a node to the beginning of the LL
int removeHead(); // remove the first node of the LL
void print(); // print the elements of the LL
node * get_head(); // access the pointer to the first node of the LL
};
Stack.h:
// Stack.h
#include "LL.h"
class Stack {
private:
LL_t intlist;
public:
Stack(); // Constructor
~Stack(); // Destructor
void push(int value);
int pop();
int isEmpty();
void print();
};
And lastly,
Stack.cpp:
// Stack.cpp
#include "Stack.h"
#include <stdio.h>
Stack::Stack() {
head= NULL;
tail= NULL;
}
Stack::~Stack() {
delete intlist;
}
int Stack::isEmpty() {
return (head==NULL);
}
void Stack::push(int value) {
head= value;
}
int Stack::pop() {
if ( !isEmpty() ) {
int temp= tail->get_data();
delete tail;
return temp;
}
return -1;
}
I am having compiling issues. It says get_data() is undefined and "head" and "tail" is undefined, even though I have " #include "LL.h" " in Stack.h and in LL.h, I have "#include "node.h" ", so they all build on one another so it should work correct? I want it to compile so I can see if I am implementing Stack.h and Stack.cpp correctly. Do you see any issues with the way I am implementing them? If so, can you point them out? Also, any idea as to why I am getting these compiling issues? Any help appreciated!
Let's look at your actual questions
Stack::Stack() {
head= NULL;
tail= NULL;
}
results in error "head" and "tail" is undefined. Now look at the header files, where are the declarations of head and tail? Answer, in the LL class not the Stack class. It's the responsibility of the LL class to initialise head and tail which it does the in the LL class default constructor. So your Stack constructor should look like this
Stack::Stack() {
}
Whenever you have a constructor for a class which contains another class a constructor for the other class will be called. In the case of Stack the default constuctor for LL is called implicitly, and this initialises head and tail for you. You don't have to do anything.
Now lets look at some more of your implementation.
Stack::~Stack() {
delete intlist;
}
intList is not a pointer, so it cannot be deleted. It's clear that you are trying to 'call` the destructor for your list, but just like the constructor this happens automatically. Your destructor should look like this
Stack::~Stack() {
}
Or you could (probably should) just remove it completely.
Moving on
int Stack::isEmpty() {
return (head==NULL);
}
Again you are trying to access head somewhere it isn't accessible. Your Stack class has an LL intlist object and that's what it should use, so (for instance)
int Stack::isEmpty() {
return intlist.get_head() == NULL;
}
Smae thing here
void Stack::push(int value) {
head= value;
}
should be
void Stack::push(int value) {
intlist.prepend(value);
}
Use the object that the stack has (the intlist) not the internals of other objects.
I'll leave you do sort out the rest. But you must understand the division of responsbilities that exist in your class design. The Stack class should not (and cannot) concern itself with the internals of the LL class. All that the operations that Stack needs to perform should be doable with the public interface of the LL class. If not then it's the LL class that needs to change.
Also note that your pop implementation is not just wrong in executuion it's wrong in concept. Pop should remove the head of the list, not the tail. A stack is a LIFO list (last in, first out) so pop removes the most recentaly added item. Now looking at the LL class there is a removeHead method (hint, hint).
I have been solving a question, Dijkstra's Algorithm, in C++. I've implemented it using adjacency list.
So I have a class for a node, a class for a minHeap, and a class for the Graph.
class node
{
int vertex,weight;
node *next;
friend class Graph;
friend class minHeap;
public:
node();
node(int,int);
};
node::node(){
vertex=weight=0;
next=0;
}
node::node(int v,int wt){
vertex=v;
weight=wt;
next=0;
}
Do I define the minHeap class this way (without a friend function) and create an object in the getDijkSP() function normally, which allows me to use the object only in that function?
class minHeap
{
node *heap;
int heapSize,capacity,*pos;
public:
minHeap(int);
void addElement(node);
node extractMin();
void minHeapify(int);
void decreaseKey(int,int);
};
minHeap::minHeap(int cap){
heap=new node[capacity=cap];
heapSize=-1;
pos=new int[cap]();
} //eliminating other methods
class Graph
{
node **adjList;
int v;
bool *visited;
public:
Graph(int);
void addEdge(int,int,int);
void removeEdge(int,int);
bool existsEdge(int,int);
void getDijkSP();
};
Graph::Graph(int vertices){
adjList=new node*[v=vertices];
for(int i=0;i<v;i++)
adjList[i]=NULL;
}
void Graph::getDijkSP(){
minHeap hp(v); //here
hp.addElement(node(0,0));
for(int i=1;i<v;i++)
hp.addElement(node(i,INT_MAX));
while(!hp.isempty()){
node temp=hp.extractMin();
cout<<temp.vertex<<" "<<temp.weight<<endl;
for(node *current=adjList[temp.vertex];current;current=current->next)
hp.decreaseKey(current->vertex,current->weight+temp.weight);
}
}
(OR) Do I define the minHeap class with a friend function, so that I can create an object of the minHeap class using the new keyword? (And this helps me define the minHeap object in the scope of the Graph class, so that I can use it in all of its functions for other capabilities as well.)
class minHeap
{
node *heap;
int heapSize,capacity,*pos;
friend class Graph; //say like this
public:
minHeap(int);
void addElement(node);
node extractMin();
void minHeapify(int);
void decreaseKey(int,int);
};
minHeap::minHeap(int cap){
heap=new node[capacity=cap]();
heapSize=-1;
pos=new int[cap]();
}
class Graph
{
node **adjList;
int v;
bool *visited;
minHeap *hp; //and do this
public:
Graph(int);
void addEdge(int,int,int);
void removeEdge(int,int);
bool existsEdge(int,int);
void getDijkSP();
};
Graph::Graph(int vertices){
adjList=new node*[v=vertices];
for(int i=0;i<v;i++)
adjList[i]=NULL;
hp=new minHeap(v); //dynamic allocation
}
void Graph::getDijkSP(){
hp->addElement(node(0,0));
for(int i=1;i<v;i++)
hp->addElement(node(i,INT_MAX));
while(!hp->isempty()){
node temp=hp->extractMin();
cout<<temp.vertex<<" "<<temp.weight<<endl;
for(node *current=adjList[temp.vertex];current;current=current->next)
hp->decreaseKey(current->vertex,current->weight+temp.weight);
}
}
I have read this and a few other articles, but specifically want to know the advantages, disadvantages and the appropriateness of both the methods for such similar kinds of questions.
I've provided the constructors for the classes for better clarity.
Short answer would be NO. I would suggest you to read up on smart pointers and rewrite this whole mess. In C++ there is no real reason to use manual allocation in so simple project as this ever.
Also instead of assigning 0 or NULL to a pointer use nullptr, which is C++ symbol only for null pointers unlike the previous mentioned C values that are actually just a int 0 which may cause some unintentional errors.
Edit in response to your comment:
So I've decided to rewrite your code using actual modern C++ instead of this C code with simple classes. In your whole example there are almost no pointers or dynamic allocations needed. I wasn't absolutely sure who exactly should own the actual nodes so from the example I assumed that the MinHeap should. Also I didn't get the point of MinHeap::pos and Graph::visited from what I could see. I can explain any part of that code in more detail, just ask which.
Here is the code:
class Node {
// Only friend class required if you insist on keeping members of Node private.
// If they aren't meant to change, consider declaring them as public and const.
template <unsigned Size> friend class Graph;
public:
Node(int v, int wt) : vertex(v), weight(wt) {}
private:
// Default values written in here right after declarations
// There is no need for a default constructor. You never call it anyway.
int vertex;
int weight;
Node* next = nullptr;
};
// Template parameter because of internal use of std::array.
// If the capacity shouldn't be constant, use std::vector and remove template.
template <unsigned Capacity>
class MinHeap {
public:
// No constructor needed
// ---------------------
// One small tip: write parameter names in function declarations
// even if they aren't needed there for better readability of your code.
void addElement(Node n) { /* impl */ }
Node extractMin() { /* impl */ }
unsigned capacity() { return Capacity; }
bool isEmpty() { return heap.isEmpty(); }
private:
// Default values written in here right after declarations
int heapSize = -1;
std::array<Node, Capacity> heap;
};
// Template parameter because of internal use of std::array.
// If the vertex count shouldn't be constant, use std::vector and remove template.
template <unsigned Vertices>
class Graph {
public:
// No constructor needed
// ---------------------
void getDjikSP() {
hp.addElement({0, 0});
for (unsigned i = 1; i < hp.capacity(); ++i)
hp.addElement({0, INT_MAX});
while (!hp.isEmpty()) {
Node tmp = hp.extractMin();
std::cout << tmp.vertex << " " << tmp.weight << std::endl;
for (Node* current = adjList[tmp.vertex]; current != nullptr; current = current->next)
hp.decreaseKey(current->vertex, current->weight + tmp.weight);
}
}
private:
// Default values written in here right after declarations
std::array<Node*, Vertices> adjList;
MinHeap<Vertices> hp;
};
There is still a lot of space for improvements of this code, for example the MinHeaP::extractMin should maybe return Node&& if it is removed from the heap or const Node& if it should return a reference to the top, etc. To address all the problems and inefficiencies this can still have I would need to see the full code with all functions.
I've stumbled upon a problem with my linked list class.
I've one abstract class Shape and multiple classes inheriting from it, like Square or Triangle etc.
I'm storing them in my List class but I don't know how to return stored object back to the pointer of Shape.
Since my explanation may seem pretty vague here is some code with expected behaviour explained.
class Shape // abstract class
{
public:
int a;
//some member virtual methods
};
class Square : public Shape
{
//using the virtual methods from Shape
};
In my main file, this is how I want to use it:
int main()
{
List<Shape*> ShapeList;
Shape *ptr;
Square a(2, 1, 1); // size, x, y coordinates
ShapeList.add(ptr);
//up to this point everything works well
// now I want my list to return a pointer to it's member
// so I can modify it
Shape *listptr;
listptr = ShapeList.findInstanceAt(0); // here's my error
listptr->a = 5; // what I want to do next
}
So as you can see I'm havingtroubles with returning proper value from my list and I don't know how to solve this.
Here's my simplified list implementation:
template <class T> class Node
{
T data;
Node *next;
public:
inline T getData()
{
return data;
}
inline Node* getNext()
{
return next;
}
};
template <class T> class List
{
Node<T> *head, *tail;
public:
List() : head(NULL), tail(NULL) { }
T* findInstanceAt(int _k)
{
if (NULL == head)
{
cout << "\nList is empty.";
return NULL;
}
else
{
Node<T> *temp = new Node<T>;
temp = head;
for (size_t k = 0; k < _k; ++k)
{
if (NULL != temp->getNext()) temp = temp->getNext();
else return NULL;
}
return temp->getData;
}
}
}
Thanks in advance for any suggestions on how to make this work.
#EDIT
Ahh I forgot to add compiler errors that I'm getting:
Error 1 error C2440: '=' : cannot convert from 'Shape **' to 'Shape *'
Do you want to store Shapes or pointers to Shapes in the list? And do you want the findInstanceAt to return the node in the list or a pointer to the node in the list? At the moment you are not consistent on these things
You store Shape* nodes in the list but the findInstanceAt returns a pointer to the node - which is a Shape** object. This is what the compiler is complaining about
You probaly need to chang
T* findInstanceAt(int _k)
to
T findInstanceAt(int _k)
So I am just working on some code and have kind of stumped myself
I have a class Node and another class BinaryTree:
class Node
{
public:
Node();
Node(int thedata, Node* right, Node* left):data(thedata), right_pointer(right), left_pointer(left){};
int get_data(){return data;}
Node* get_right() {return right_pointer;}
Node* get_left() {return left_pointer;}
private:
int data;
Node* right_pointer;
Node* left_pointer;
};
class BinaryTree
{
private:
Node* root;
void add_tree_node(Node*& root,int data);
void print_tree(Node* root);
public:
BinaryTree();
void print_tree();
void add_tree_node(int data);
};
My issue is with this command:
add_tree_node(root->get_right(), data);
I get an error saying: no instance of overloaded function.
which get_right() returns a pointer to the pointer and was wondering if there was a better way of doing this instead of the two options below.
when I do this:
Node* right = root->get_right();
add_tree_node(right, data);
or
add_tree_node(root->right_link,data);
it works and I understand why it works because we are passing in the pointer itself and not the value.
Node* &get_right() {return right_pointer;}
Node* &get_left() {return left_pointer;}
node->get_right() returns an rvalue. add_tree_node() takes a non-const reference. You can only make a non-const reference out of an lvalue, not an rvalue. Therefore the return value of node->get_right() cannot be turned into a non-const reference unless you put it into a local variable first.
That said, why does add_tree_node() take a reference to begin with? It's already taking a pointer, so you can mutate the Node all you want without needing a reference.
Sounds to me like you need an insert( & node, data) function
then in your main, you can create a new binary tree with your constructor with something like this: Node binaryTree = new Node();
from there, you can insert nodes like this: binaryTree->insert( binaryTree, data );
#include <cstdlib>
#include <iostream>
#include "Node.h"
#ifndef HW4_H
#define HW4_H
using namespace std;
/**
You are to implement the two functions in this class.
You can add any other method or members to it as well.
However, you cannot change their signature.
**/
class HW4{
public:
int count(Node* r) const
{
if(r->next==NULL&&r->bro==NULL) { return 0;}
if(r.isLeaf())
{
return ((1+count(r->next)+count(r->bro)));
}
count(r->next);
}
/*
This method will return true if the tree rooted at node sn can answer
the demand induced by its leaves.
*/
bool canDemandBeAnswered(Node* root)
{
if(count(root)>(root.getCapacity()))
{
return 0;
exit(0);
}
else
{
return (canDemandBeAnswered(root->next)&&canDemandBeAnswered(root->bro));
}
}
/*
This method should return a linked list of nodes representing the
customers with the overall highest revenue.
The resulting list should conform to the capacity limitations.
*/
// Node* getBestCustomers(Node* root);
};
#endif
#include <cstdlib>
#ifndef NODE_H
#define NODE_H
/**
The Node class. You must implement the two methods isLeaf() and addChild(Node*) below.
Otherwise, you can add any methods or members your heart's desire.
The only limitation is that they have to be in this file.
**/
class Node {
private:
int capacity;
int price;
public:
/**
Hint: to be used for saving the Node's children and for returning the linked list
**/
Node* next;
Node* bro;
Node(){
capacity = 0;
price = 0;
}
Node(int capacity_){
capacity = capacity_;
price = 0;
}
//should return true if this node has no children, false otherwise.
//this method adds a child to this node.
int getCapacity(){
return capacity;
}
int getPrice(){
return price;
}
void setPrice(int price_){
price = price_;
}
bool isLeaf()
{
if((this->next)->capacity==0)
return 1;
else return 0;
}
void addChild(Node* child)
{
Node* temp;
if(this->next!=NULL)
{
temp=this->next;
child->bro=temp;
this->next=child;
}
else
this->next=child;
}
};
#endif
I get the following error: "isLeaf() has not been declared". I don't understand why - I declared both.
bool canDemandBeAnswered(Node* root)
{
if(count(root)>(root.getCapacity()))
This attempts to call getCapacity on a Node *. But Node * doesn't have a function called getCapacity -- Node does.
You can use (*root).getCapacity() or the shorthand, root->getCapacity().
if(r.isLeaf())
You have the same issue here. r is a Node *.
Did you mean r->isLeaf() instead of r.isLeaf(), since r is a pointer?
You should be using -> instead of . to access those functions because r is a pointer.
Member access for pointers is different. You must use the indirection operator ->. These are not the actual objects but just pointers to them.