i'm attempting to implement three methods currently a get_first(), get_last() and print_node(). get_first() will return the head of a list, get_last() the tail, and print_node() will just print the data field of a node sent to it. im trying to implement but continually getting pointer errors for any changes that i make.
here's my node.h header:
class Node
{
private:
int data;
Node *next;
Node *prev;
friend class LinkedList;
};
class LinkedList
{
private:
Node *head;
Node *tail;
public:
LinkedList();
~LinkedList();
bool empty();
void insert_left(int v);
void insert_right(int v);
Node* get_first();
Node* get_last();
void print_list();
void print_node(Node *n);
void remove_left();
void remove_right();
protected:
void add(Node *v, int d);
void remove(Node *v);
};
here are the relevant portions of my list.cpp class implementation file:
#include <iostream>
#include "node.h"
using namespace std;
LinkedList :: LinkedList()
{
head = new Node;
tail = new Node;
head->next = tail;
tail->prev = head;
}
LinkedList :: ~LinkedList()
{
while(!empty())
{
remove_left();
}
delete head;
delete tail;
}
void LinkedList :: add(Node *v, int d)
{
Node *u = new Node;
u->data = d;
u->next = v;
u->prev = v->prev;
v->prev->next = v->prev = u;
}
void LinkedList :: print_list()
{
Node *tmp = head;
while(tmp != NULL)
{
cout << tmp->data << endl;
tmp = tmp->next;
}
}
void LinkedList :: print_node(Node *n)
{
Node *tmp = n;
cout << tmp->data << endl;
}
Node LinkedList :: get_first()
{
return head;
}
Node LinkedList :: get_last()
{
return tail;
}
finally here's my main function in a file called main.cpp:
#include <cstdlib>
#include <iostream>
#include "list.cpp"
using namespace std;
int main(int agrc, char **argv)
{
LinkedList *l = new LinkedList();
//LinkedList *m = new LinkedList();
l->insert_left(200);
l->insert_left(700);
l->insert_left(300);
Node *temp = l->get_first();
//l->print_list();
l->print_node(temp);
delete l;
return 0;
}
here's the current error output:
g++ main.cpp -o main
In file included from main.cpp:3:
list.cpp:85: error: prototype for ‘Node LinkedList::get_first()’ does not match any in class ‘LinkedList’
node.h:24: error: candidate is: Node* LinkedList::get_first()
list.cpp:90: error: prototype for ‘Node LinkedList::get_last()’ does not match any in class ‘LinkedList’
node.h:25: error: candidate is: Node* LinkedList::get_last()
make: *** [main] Error 1
i'm not sure of the exact changes to make but i think it has to do with how i'm returning the head in the get_first() and last() functions. Please excuse the length of the post.
You are returning Node* in function declaration but in definition you have Node as the return type. Use this
Node* LinkedList :: get_first()
{
return head;
}
Node* LinkedList :: get_last()
{
return tail;
}
Data members head and tail are defined as
Node *head;
Node *tail;
that is they are pointers to Node. So if any function returns either head or tail then its return type has to be Node *
So these member function definitions
Node LinkedList :: get_first()
{
return head;
}
Node LinkedList :: get_last()
{
return tail;
}
are wrong. They return head and tail but have no the return type Node * and their definitions do not coinside with theor declarations in the class.
Also the constructor definition is wrong. It shoild look as
LinkedList :: LinkedList() : head( nullptr ), tail( nullptr )
{
}
In this case member function empty should be declared as
bool empty() const;
and defined as
bool empty() const { return ( head == nullptr ); }
Related
please help. I am getting segmentation fault when i try to print elements in this linked list.
i first declare a class and the function to insert and display the elements of the list are its functions.
code:
#include <iostream>
using namespace std;
struct node{
int data;
node *next;
};
class ll{
node *head,*tail;
public:
void push(int x){
node *temp = new node;
temp->data = x;
temp->next = NULL;
if(head == NULL){
head = temp;
tail= temp;
}
else{
tail->next = temp;
tail= temp;
}
}
void show(){
node *n = head;
while(n!=NULL){
cout<<n->data<<"\n";
n = n->next;
}
}
};
int main()
{
ll a;
a.push(1);
a.push(2);
a.show();
return 0;
}
Neither the data member head nor the data member tail are initialized by nullptr. So the program has undefined behavior.
You could write in the class definition
class ll{
node *head = nullptr, *tail = nullptr;
//...
Bear in mind the structure node should be member of the class ll. For example
class ll{
struct node{
int data;
node *next;
} *head = nullptr,*tail = nullptr;
public:
void push( int x ){
node *temp = new node { x, nullptr };
if( head == NULL ){
head = tail = temp;
}
else {
tail = tail->next = temp;
}
}
//...
Instead of initializing data members in the class definition you coudl initialize them in the default constructor like for example
class ll{
struct node{
int data;
node *next;
} *head,*tail;
public:
ll() : head( nullptr ), tail( nullptr ) {}
// ...
Also you need at least to define the destructor and either explicitly define the copy constructor and copy assignment constructor or define them as deleted. For example
class ll{
struct node{
int data;
node *next;
} *head,*tail;
public:
ll() : head( nullptr ), tail( nullptr ) {}
~ll() { /* must be defined */ }
ll( const LL & ) = delete;
ll & operator =( const ll & ) = delete;
// ...
The problem is that you don't set head to NULL when you list is created. Same issue applies to tail. This is a job for the constructor
class ll {
node *head,*tail;
public:
ll() { head = tail = NULL; }
void push(int x) {
...
In the middle of our class and currently we are stuck on the following compiling error. Not sure if it's the compiler or our code. Any help or guidance would be appreciated.
Our header file:
//specification file for the numberlist class
#ifndef NUMBERLIST_H
#define NUMBERLIST_H
class NumberList
{
private:
//declares a structure for the list
struct ListNode
{
double value; // value in the node
struct ListNode *next; //to point to the next node
};
ListNode *head; // list head pointer
public:
// construcorr
NumberList()
{
head = nullptr;
}
~NumberList();
//linked list operations
void appendNode(double);
void insertNode(double);
void deleteNode(double);
void dispayList()const;
void NumberList::appendNode(double num)
{
ListNode *newNode;
ListNode *nodePtr;
//allocate a new node and store num there
newNode = new ListNode;
newNode->value = num;
newNode->next = nullptr;
//if there are no nodes in the listmake newNode first node
if (!head)
head = newNode;
else // otherwise insert newNode at end
{
//initialize nodePtr to head of list
nodePtr = head;
//find the last node in the list
while (nodePtr->next)
nodePtr = nodePtr->next;
// insert newNode as the last node
nodePtr->next = newNode;
}
}
};
#endif
Our CPP file:
//this program demonstrates a simple append operation on a linked list
#include <iostream>
#include "NumberList.h"
using namespace std;
int main()
{
//define a numberList object
NumberList list;
//append some values
list.appendNode(2.5);
list.appendNode(7.9);
list.appendNode(12.6);
system("pause");
return 0;
}
You have to close class declaration end brace before starting function definition.
//specification file for the numberlist class
#ifndef NUMBERLIST_H
#define NUMBERLIST_H
class NumberList
{
private:
//declares a structure for the list
struct ListNode
{
double value; // value in the node
struct ListNode *next; //to point to the next node
};
ListNode *head; // list head pointer
public:
// construcorr
NumberList()
{
head = nullptr;
}
~NumberList();
//linked list operations
void appendNode(double);
void insertNode(double);
void deleteNode(double);
void dispayList()const;
};
void NumberList::appendNode(double num)
{
ListNode *newNode;
ListNode *nodePtr;
//allocate a new node and store num there
newNode = new ListNode;
newNode->value = num;
newNode->next = nullptr;
//if there are no nodes in the listmake newNode first node
if (!head)
head = newNode;
else // otherwise insert newNode at end
{
//initialize nodePtr to head of list
nodePtr = head;
//find the last node in the list
while (nodePtr->next)
nodePtr = nodePtr->next;
// insert newNode as the last node
nodePtr->next = newNode;
}
}
#endif
You first declared the function in the class declaration, then also defined it inside the class declaration. You either have to move the definition outside, in a corresponding .cpp file that implements the class, i.e. the code below should be in the implementation cpp file:
void NumberList::appendNode(double num)
{
// implementation
}
or define it inline in the class
class NumberList
{
// ....
void appendNode(double num) // automatically inline
{
// implement
}
};
A third option is to define it in the header file but outside the class, however in this case you have to explicitly mark it as inline, since otherwise including your header in multiple cpp files will lead to a linker error due to a duplicate symbol
inline void NumberList::appendNode(double num) // this can now be in the header file
{
// implementation
}
You cannot have both a declaration and a definition inside a class.
I have a header file containing this class definition:
class visitorlist {
struct Node {
visitor vis;
Node* next;
};
Node* head;
Node* tail;
public:
visitorlist() { //written here to have it as inline.
head = NULL;
tail= NULL;
}
~visitorlist();
int lengthvl();
void add(const visitor);
void popandexit();
void transfer(visitorlist);
void deletenode(Node*);
int refiprio();
int refioffno();
int refifloor();
visitor reravi();
bool isempty();
Node* rehead();
};
and in a source file with the above header included I have:
Node* visitorlist::rehead() {
return head;
}
This causes an error: 'Node' does not name a type.
Isn't Node on the scope of the function?
Use
visitorlist::Node* visitorlist::rehead() {
return head;
}
Or, since C++11:
auto visitorlist::rehead() -> Node* {
return head;
}
Just started learning c++ for a class, I can't figure out what is wrong with this code! I'm making a stack class with a helper class nested inside it called node that acts as a linked list. The error I'm getting is on line 12 and is:
Stack.cpp: In destructor ‘Stack::~Stack()’:
Stack.cpp:12:24: error: request for member ‘getNext’ in ‘((Stack*)this)->Stack::node’, which is of non-class type ‘Stack::Node*’
Here's my code:
#include "Stack.h"
Stack:: Stack ()
{
height = 0;
node = 0;
}
Stack:: ~Stack()
{
while(node != 0){
Node *next = *node.getNext();
delete node;
node = next;
}
node = 0;
}
And Here's my header file:
using namespace std;
class Stack
{
private:
int height;
class Node{
private:
int data;
Node* next;
public:
void setData(int x){
data = x;
}
void setNext(Node* x){
next = x;
}
int getData(){
return data;
}
Node* getNext(){
return next;
}
};
Node* node;
public:
Stack();
~Stack();
void push(int x);
int pop();
int peek();
int getHeight();
bool isEmpty();
};
Node *next = *node.getNext();
should be
Node *next = (*node).getNext();
Since . operator has higher precedence than * deference operator.
You can also use:
Node *next = node->getNext();
creating some old data structures in C++. Currently I am having an issue with a doubly-linked list class:
List.h:
template <class T>
class List{
private:
int size;
struct listNode{
T data;
listNode* next;
listNode* prev;
listNode(T newData);
};
listNode * head;
listNode * tail;
listNode * curr;
listNode * find(listNode * place, int k);
void removeCurrent(listNode * temp);
public:
List();
int getSize() const;
void insert(int loc, T data);
void remove(int loc);
T const & getItem(int loc) const;
void print();
};
List.cpp:
#include "List.h"
#include <iostream>
using namespace std;
template<class T>
List<T>::List(){
size = 0;
head->next = tail;
head->prev = NULL;
tail->prev = head;
tail->next = NULL;
}
// getSize: public method that returns the size of the list
template<class T>
int List<T>::getSize() const {
return size;
}
// insert: public method that inserts data into the list
template<class T>
void List<T>::insert(int loc, T data){
if(loc <1){
cout<<"Invalid Location"<<endl;
return;
}
curr = find(head,loc-1);
listNode * newNode = new listNode(data);
newNode->next = curr->next;
newNode->prev = curr;
newNode->next->prev = newNode;
curr->next = newNode;
size++;
}
// remove: public method that inserts data into the list
template<class T>
void List<T>::remove(int loc){
if(loc <1){
cout<<"Invalid Location"<<endl;
return;
}
curr = find(head,loc); // Find the node infront of the target
removeCurrent(curr); // Remove that node
}
// removeCurrent: helper function that removes the current node
template<class T>
void List<T>::removeCurrent(listNode* temp){
listNode* t = temp->next;
temp->data = t->data; // HACK: take data from next node
temp->next = t->next;
t->next->prev = temp;
delete t;
t=NULL;
size--;
}
// find: private helper function that returns a pointer to the k-1 node
template<class T>
listNode * List<T>::find(listNode * place, int k){
if((k==0) || (place==NULL))
return place;
else return find(place->next,k-1);
}
// getItem: returns data at location loc
template<class T>
T const& List<T>::getItem(int loc) const{
curr = find(head,loc);
return curr->data;
}
// print: prints the sequence of variables in the list
template<class T>
void List<T>::print()
{
curr = head;
while(curr->next != tail){
curr = curr->next;
cout<<curr->data<<endl;
}
}
//listNode constructor
template<class T>
List<T>::listNode::listNode(T newdata):data(newdata),next(NULL),prev(NULL)
{}
The error I'm getting is the following:
error: 'listNode' does not name a type.
I have tried different suggestions offered in similar troubleshooting posts, but I'm still getting this error. I have a main.cpp that includes List.cpp, but it's practically empty.
You're going to have to specify which listNode you're talking about at the find method's return type because you defined it as a member of the List class and you're also going to have to use typename (because List<T> is a dependent scope).
template <class T>
typename List<T>::listNode* List<T>::find(listNode* place, int k)
{
if ((k == 0) || (place == NULL))
return place;
else
return find(place->next, k-1);
}
Assuming you're using c++11, you may also want to use nullptr instead of NULL since its safer and use the initializer list at the List constructor.