everyone! I am making my own linked list template to both practice and for future use; however, I ran into a problem with one of my functions:
Node* LinkedList::FindNode(int x); //is meant to traverse the list and return a pointer to the containing x as its data.
When trying to declare it in my implementation file, I keep getting messages of Node being undefined and incompatibility errors.
Here is my header file:
#pragma once
using namespace std;
class LinkedList
{
private:
struct Node
{
int data;
Node* next = NULL;
Node* prev = NULL;
};
//may need to typedef struct Node Node; in some compilers
Node* head; //points to first node
Node* tail; //points to last node
int nodeCount; //counts how many nodes in the list
public:
LinkedList(); //constructor
~LinkedList(); //destructor
void AddToFront(int x); //adds node to the beginning of list
void AddToEnd(int x); //adds node to the end of the list
void AddSorted(int x); //adds node in a sorted order specified by user
void RemoveFromFront(); //remove node from front of list; removes head
void RemoveFromEnd(); //remove node from end of list; removes tail
void RemoveSorted(int x); //searches for a node with data == x and removes it from list
bool IsInList(int x); //returns true if node with (data == x) exists in list
Node* FindNode(int x); //returns pointer to node with (data == x) if it exists in list
void PrintNodes(); //traverses through all nodes and prints their data
};
If someone can help me define a function that returns a Node pointer, I would greatly appreciate it!
Thank you!
Since Node is declared within another class, did you remember to include the class name when referring to it in your implementation?
LinkedList::Node *LinkedList::FindNode(int x) { ... }
In the class declaration the prefix isn't required because the declaration is inside the class, and therefore Node is implicitly available.
Related
I'm in CS2 and we're just learning about linked lists and I have to code the parameterized constructor of a linked list class (node based). I don't really understand the node lists, so any help of what's going on here or how to approach would be helpful! I have the following Node class given:
class Node {
friend class NodeList;
public:
Node() : m_next(NULL) {}
Node(const DataType& data, Node* next = NULL) :
m_next(next), m_data(data) {}
Node(const Node& other) : m_next(other.m_next),
m_data(other.m_data) {}
DataType& data() { return m_data; }
const DataType& data() const { return m_data; }
private:
Node* m_next;
DataType m_data;
};
and I'm trying to create the parameterized constructor for the following class:
Class NodeList {
public:
NodeList();
NodeList(size_t count, const int value);
private:
Node* m_head;
}
, where the parameterized constructor is supposed to have 'count' nodes initialized to 'value'.
Thank you!
Solving a problem like this has 3 parts.
Break the problem down into smaller, simpler tasks that make it easier to solve
Do the smaller tasks
Use them to solve the big problem.
What would make it easy to solve this problem? Adding one value to a list is easier than adding multiple values to a list, so let's write a function to do that.
To add one value at the beginning of the list,
We can create a new node with that value
We have the new node point to the current first node
We set the current first node to the new node.
Let's call our function prepend, since it prepends the value to the list.
class NodeList {
public:
// The head should be set to null initially
NodeList()
: m_head(nullptr)
{
}
// This function takes a value and adds it to the beginning of the list
void prepend(const DataType& value) {
// The new node uses the current head as the next value
Node* newNode = new Node(value, m_head);
// We set the current head to the new node.
m_head = newNode;
}
Now, adding a value multiple times is easy. We can just call prepend once for each time we want to add an item.
class NodeList {
public:
// The head should be set to null initially
NodeList()
: m_head(nullptr)
{
}
// This function takes a value and adds it to the beginning of the list
void prepend(const DataType& value) {
// The new node uses the current head as the next value
Node* newNode = new Node(value, m_head);
// We set the current head to the new node.
m_head = newNode;
}
NodeList(size_t count, const DataType& value)
: m_head(nullptr) // The head still has to be null initially
{
for(size_t i = 0; i < count; i++)
{
prepend(value);
}
}
};
I'm trying to create a spell checking program in C++ by reading in a dictionary from a .txt file. I've got the read in function working perfectly fine, the issue I'm coming across is when I try to navigate and add to my linked list.
When I try to set the pointer of the newest node to add, to the value of the head pointer, I'm getting an error stating No viable conversion from 'Node' to 'Node *'.
What is the best way to perform this conversion.
I've already tried turning my 'Node Head;' inside of my linked list class to a pointer but receive the same error.
To start I created my Node struct (Declared in a header file)
struct Node
{
private:
std::string word;
Node *nextNode;
public:
//Default constructor
Node();
~Node();
//My Setters and getters for the class
void setWord(std::string _word) { word = _word; }
std::string getWord() { return word; }
void setNode(Node *_nextNode) { nextNode = _nextNode; }
Node getNode() { return *nextNode; }
};
Followed by my LinkedList Class (Also declared in a Header file)
class LinkedList
{
private:
Node head;
int listSize;
public:
LinkedList();
~LinkedList();
void setListSize(int _listSize) { listSize = _listSize; }
int getListSize() { return listSize; }
void setHead(Node _head) { head = _head; }
Node getHead() { return head; }
//Function that adds the next node to the head
void addToHead(LinkedList &myList, Node &myNode);
};
Heres my Function
void LinkedList::addToHead(LinkedList &myList, Node &myNode)
{
myNode.setNode(myList.getHead().getNode());
//Here is where I'm getting my error
//"No viable conversion from 'Node' to 'Node *'
myList.setHead(myNode);
}
The LinkedList class shouldn't own the first Node.
The member head should be a Node* width default value nullptr (the list is empty).
listSize should also have a default value assigned.
LinkedList() head(nullptr), listSize(0) {};
Edit
Personally I would avoid to force the external code to manage the single nodes.
Keep an implementation independent interface.
class LinkedList
{
private:
Node *head_;
int size_;
public:
LinkedList();
~LinkedList();
int size() const { return listSize; }
// insert after the i-th element
void insert(std::size index, std::string const& word);
// return the i-th element
std::string &at(std::size index);
std::string const &at(std::size index) const;
// removes the i-th element
void remove(size::size index);
};
In this way you centralize all list manipulation code into the LinkedList class.
You should also consider problems related to copying a LinkedList object.
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 two classes: Database and Node as a nested class, is it possible to have a method of Node that will return a Node*?
I tried to set the method nextNode return type as Node* but I get a compilation error: 'Node' does not name a type
Databse.h
class Database
{
public:
Database();
Database& operator+=(const Client&);
~Database();
private:
class Node //node as nested class
{
public:
Node(); //ctor
void setHead(Client*&); //add head node
Node* nextNode(Node*&); //return new node from the end of he list
private:
Client* data; //holds pointer to Client object
Node* next; //holds pointer to next node in list
};
Node *head; //holds the head node
};
nextNode method declaration in Databse.cpp:
Node* Database::Node::nextNode(Node*& start)
{
....
....
return current->next;
}
Thanks.
Node is nested in Database, so you need the scope for the return type:
DataBase::Node* Database::Node::nextNode(Node*& start)
^^^^^^^^^^
The parameter is already in scope, so you may leave it as is.
Additionally to juanchopanza's answer, C++11's trailing return type allows you to declare it in-scope :
auto Database::Node::nextNode(Node*& start) -> Node* {
// ...
}
Please delete.
I want to implement a linked list. Unfortunately I'm not sure whether I'm on the right track.
#include <iostream>
using namespace std;
class Node {
friend class List;
public:
int value;
private:
Node *next;
};
class List {
public:
List ();
~List ();
Node * first() const;
Node * next(const Node * n) const;
void append (int i);
Node* head;
};
List::List() {
Node* head = new Node();
}
List::~List() {
while(head != NULL) {
Node * n = head->next;
delete head;
head = n;
}
}
Node * List::first() const {
return head; // this could also be wrong
}
Node * List::next(const Node * n) const {
return n + 1; // ERROR
}
void List::append(int i) {
Node * n = new Node;
n->value = i;
n->next = head;
head = n;
}
int main(void) {
List list;
list.append(10);
return 0;
}
When I try to return an element in next() I get this error:
In member function ‘Node* List::next(const Node*) const’:|
error: invalid conversion from ‘const Node*’ to ‘Node*’ [-fpermissive]|
Could somebody please help me?
EDIT:
I've updated the error-line.
I think what you mean to be doing is returning the Node's next:
Node * List::next(const Node * n) const {
return n->next;
}
You would use pointer arithmetic if this were an array where the size of each object was constant, but linked lists can't use pointer arithmetic. If you have an iterator, you could use the '++' operator to get the next object, but with this just stick to returning the node's next field.
I'm assuming this will also work because even though next is declared as private, you've made List a friend.
You are thinking that consecutive nodes are in consecutive blocks of memory, and they are not. Linked lists have nodes in random places in memory, which is why "next" points to the NEXT node. You cannot increment or add as you are trying (well you can, but semantically it would be incorrect.)