I have to write a Queue in C++ using a List file that I created earlier and I'm having a rough time getting everything to compile.
The issue I am currently having is that when I compile I get the error:
Queue.h:7:2: error: 'List' does not name a type
How do I go about properly connecting my Queue file and my List file?
Here are the files I am using:
List.h
//an item in the list
struct ListNode {
int _value;
ListNode * _next;
};
class List {
public:
//Head of list
ListNode * _head;
int remove_front();
void insertSorted( int val );
void append (int val);
void prepend (int val);
int lookup( int _value );
int remove( int val );
void print();
List();
~List();
};
List.cc
//
// Implement the List class
//
#include <stdio.h>
#include "List.h"
ListNode * _head = new ListNode();
//remove the first node in the list
int
List::remove_front(){
int ret;
if(_head == 0){
return -1;
}
ret = _head->_value;
ListNode *temp = new ListNode();
temp = _head->_next;
delete(_head);
_head = temp;
return ret;
}
//
// Inserts a new element with value "val" in
// ascending order.
//
void
List::insertSorted( int val ){
ListNode* new_node = new ListNode();
new_node->_value = val;
ListNode* current = new ListNode();
if(_head == 0){
_head = new_node;
}else{
current = _head;
ListNode* prev = 0;
while(current != 0){
if(new_node->_value > current->_value){
prev = current;
current = current->_next;
}else{
break;
}
}
if(current == _head){
new_node->_next = _head;
_head = new_node;
}else{
new_node->_next = current;
prev->_next = new_node;
}
}
}
//
// Inserts a new element with value "val" at
// the end of the list.
//
void
List::append( int val ){
//create a new node to hold the given value
ListNode *new_node = new ListNode();
new_node->_value = val;
//if the list is empty
if(_head == 0){
//set the new node to be the head
_head = new_node;
return ;
}
//create a node pointer to the current position (starting at the head)
ListNode *current = new ListNode();
current = _head;
//Loop through the list until we find the end
while(current->_next != NULL){
current = current->_next;
}
current->_next = new_node;
}
//
// Inserts a new element with value "val" at
// the beginning of the list.
//
void
List::prepend( int val ){
ListNode *new_node = new ListNode;
new_node->_value = val;
if(_head == 0){
_head = new_node;
return ;
}
ListNode *temp = new ListNode;
temp = _head;
_head = new_node;
_head->_next = temp;
}
// Removes an element with value "val" from List
// Returns 0 if succeeds or -1 if it fails
int
List:: remove( int val ){
if(_head == 0){
printf("List is already empty.\n");
return -1;
}
ListNode *current = new ListNode();
ListNode* prev = new ListNode();
current = _head;
while(current != 0){
if(current->_value == val){
if(current == _head){
_head = _head->_next;
delete(current);
return 0;
}else{
prev->_next = current->_next;
delete(current);
return 0;
}
}else{
prev = current;
current = current->_next;
}
}
return -1;
}
// Prints The elements in the list.
void
List::print(){
ListNode* current = new ListNode();
while(current != 0){
printf("%d\n", current->_value);
current = current->_next;
}
}
//
// Returns 0 if "value" is in the list or -1 otherwise.
//
int
List::lookup(int val){
ListNode * current = new ListNode();
current = _head;
while(current != NULL){
if(current->_value == val){
return 0;
}
else{
current = current->_next;
}
}
return -1;
}
//
// List constructor
//
List::List(){
}
//
// List destructor: delete all list elements, if any.
//
List::~List(){
ListNode* current = _head;
while(current != NULL){
ListNode* next = current->_next;
delete current;
current = next;
}
}
Queue.h
#ifndef LIST_H
#define LIST_H
class Queue {
public:
List* queue_list;
void enqueue(int val);
int dequeue();
Queue();
~Queue();
};
#endif
Queue.cc
#include <stdio.h>
#include "List.h"
#include "Queue.h"
List *queue_list = new List();
void
Queue::enqueue(int val){
this->queue_list->prepend(val);
}
int
Queue::dequeue(){
int value = this->queue_list->remove_front();
return value;
}
Queue::Queue(){
//do nothing
}
Queue::~Queue(){
}
queue_main.cc
#include <stdio.h>
#include "Queue.h"
#include "List.h"
Queue *queue;
int main(){
}
Thanks for the help!
The compiler tells you what's wrong:
Queue.h:7:2: error: 'List' does not name a type
While reading Queue.h, the compiler cannot possibly know what List is, as there is nothing in this file that defines it.
You simply have to add a forward declaration:
#ifndef LIST_H
#define LIST_H
class List; // this is a forward declaration.
class Queue {
public:
List* queue_list;
void enqueue(int val);
int dequeue();
Queue();
~Queue();
};
#endif
Alternatively (but not necessary here), you could simply #include List.h. The rule of thumb is: Use forward declaration if possible. If the compiler complains about it, replace it by the corresponding include. The include is only necessary if the compiler must know the size of the class / struct.
Related
I am trying to make a way to take two Linked List objects (doubly-linked), say LL1 and LL2, and remove the 'overlapping' elements within LL1 which also appear in LL2.
So for example if:
LL1 = {1,2,3};
LL2 = {9,2,8};
I want an output of:
LL1 = {1,3};
I am trying to do this via overloading the '-=' operator to work with two linked list objects. It compiles fine, but I'm getting a 'segmentation fault (core dumped)' error during runtime at the '-=' operator call. Not sure why. Below is my code. Any help would be appreciated, thankyou kindly.
Node.h:
// Node.h
/*******************************/
// Last Updated: Tues Aug 31 2021
// Program Description: Header file for Node
#ifndef NODE_H
#define NODE_H
#include <iostream>
#include <cstdlib>
#include "EToll.h"
using namespace std;
class Node {
public:
typedef EToll value_type; //typedef - now value_type is synonym for EToll object
//Constructors:
Node(); //default
Node(value_type&); //constructor with 1 arg - data item
Node(const value_type& i, Node* n, Node* p); //specific constructor with 3 arguments
//Destructor:
~Node();
//mutators (setters):
void set_next(Node*);
void set_prev(Node*);
void set_data(const value_type&);
//accessors (getters):
Node* get_next() const;
Node* get_prev() const;
value_type& get_data();
private:
Node* next; //ptr to next (or NULL)
Node* prev; //ptr to prev (or NULL)
value_type data; //the payload
};
#endif
Node.cpp:
// Node.cpp
/*******************************/
// Last Updated: Tues Aug 31 2021
// Program Description: Implementation of Node
#include "Node.h"
#include <cstdlib>
//Constructors:
Node::Node() //default constructor
{
data = value_type(); //creates an empty EToll object, since value_type is a synonym for EToll
next = NULL;
prev = NULL;
}
Node::Node(value_type& item) //constructor with 1 argument - a data item
{
data = item;
next = NULL;
prev = NULL;
}
Node::Node(const value_type& i, Node* n, Node* p) //constructor with 3 arguments
{
data = i;
next = n;
prev = p;
}
//Empty destructor:
Node::~Node(){}
//Mutators (setters):
void Node::set_next(Node* next_ptr) {next = next_ptr;}
void Node::set_prev(Node* prev_ptr) {prev = prev_ptr;}
void Node::set_data(const value_type& new_data) {data = new_data;}
//Accessors (getters):
Node* Node::get_next() const {return next;}
Node* Node::get_prev() const {return prev;}
/* Note that get_data() has Node::value_type& instead of value_type& as it's return type as the
compiler doesn't check if the return type of a function is part of a member function, and thus
it doesn't look in Node for a value_type. A more detailed explanation can be found at: https://stackoverflow.com/questions/68991650/error-value-type-does-not-name-a-type-in-c */
Node::value_type& Node::get_data() {return data;}
LinkedList.h:
// LinkedList.h
/*******************************/
// Last Updated: Tues Aug 31 2021
// Program Description: Header file for LinkedList
#ifndef LINKEDLIST_H
#define LINKEDLIST_H
#include "Node.h"
#include <iostream>
#include <cstdlib>
#include <string>
class LinkedList
{
public:
typedef Node::value_type value_type;
//Constructor:
LinkedList();
//Destructor:
~LinkedList();
//Insert function:
//void insert(value_type& item);
//length function:
int length();
//count function:
int count(string);
//totalIncome function:
double totalIncome();
//addTo functions:
void addToHead(value_type&);
void addToTail(value_type&);
//accessors (getters):
value_type& getHead();
Node* getHeadAdd();
value_type& getTail();
//remove functions:
void removeFromHead();
void removeFromTail();
void remove(string);
void removeByNode(Node* c); //remove a particular node
//search funciton:
//Preconditions: None
//Postconditions: Current points to the first Node storing the target, and true is returned. If not present, current is NULL and false is returned
bool search(const value_type& target);
//concatenation operator (+=) overload:
//Preconditions: LL1 and LL2 are instances of LinkedList
//Postconditions: Each Node of LL2 is traversed. At each individual Node, itis appended to LL1
LinkedList operator += (const LinkedList& LL2);
//remove overlap operator (-=) overload:
//Preconditions: LL1 and LL2 are instances of LinkedList
//Postconditions: Each Node of LL2 is traversed. At each individual Node, it's match is searched for within LL1. If a match is found, the matching Node in LL1 is deleted and the next node in LL2 is traversed
LinkedList operator -= (const LinkedList& LL2);
//NEED A .COUNT FUNCTION!!
private:
Node* head;
Node* tail;
Node* current;
};
//stream insertion operator (<<) overload:
//Preconditions: LinkedList obj "LL" exists and we wish to output it
//Postconditions: LL exists without change
ostream& operator << (ostream& out, LinkedList& LL);
#endif
LinkedList.cpp:
// LinkedList.cpp
/*******************************/
// Last Updated: Wed Aug 31 2021
// Program Description: Implementation of LinkedList
#include "LinkedList.h"
#include <cstdlib>
//Constructors:
LinkedList::LinkedList() //default constructor
{
head = NULL;
tail = NULL;
current = NULL;
}
//Empty destructor:
LinkedList::~LinkedList(){}
//length() function:
//Preconditions: None
//Postconditions: A count of the nodes is returned (ie no of nodes in the LinkedList)
int LinkedList::length()
{
int answer = 0;
for (current = head; current != NULL; current = current->get_next())
{
answer++;
}
return answer;
}
//count function:
int LinkedList::count(string type)
{
int returnCount = 0;
//cycle through LinkedList:
for (current = head; current != NULL; current = current->get_next())
{
//check for match:
if (type == current->get_data().get_type())
{
//increment the counter
returnCount++;
}
}
return returnCount;
}
//totalIncome function:
double LinkedList::totalIncome()
{
double returnTotal = 0;
//cycle through LinkedList:
for (current = head; current != NULL; current = current->get_next())
{
returnTotal = returnTotal + current->get_data().get_charge();
}
return returnTotal;
}
//addToHead function:
//Preconditions: None
//Postconditions: A new node storing the supplied item is created and linked in to be list's new head
void LinkedList::addToHead(Node::value_type& item)
{
Node* newNode = new Node(item);
//Check if the list is empty:
if (length() == 0)
{ //list is empty, so:
head = newNode;
tail = newNode;
} else
{ //list is not empty, so:
head->set_prev(newNode);
newNode->set_next(head);
head = newNode;
}
/*
head = new Node(item, head, NULL);
//In case the list is empty:
if (tail == NULL)
{
tail = head;
}
*/
}
//addToTail function:
//Preconditions: None
//Postconditions: A new node storing the supplied item is created and linked in to be list's new tail
void LinkedList::addToTail(Node::value_type& item)
{
Node* newNode = new Node(item);
//Check if the list is empty:
if (length() == 0)
{ //list is empty, so:
head = newNode;
tail = newNode;
} else
{ //list is not empty, so:
tail->set_next(newNode);
newNode->set_prev(tail);
tail = newNode;
}
}
//getHead function:
Node::value_type& LinkedList::getHead()
{
return head->get_data();
}
//getHeadAdd function:
Node* LinkedList::getHeadAdd()
{
return head->get_next()->get_prev();
}
//getTail function:
Node::value_type& LinkedList::getTail()
{
return tail->get_data();
}
//removeFromHead function:
void LinkedList::removeFromHead()
{
Node* temp;
temp = head->get_next();
if (head != NULL)
{
temp->set_prev(NULL);
head = temp;
} else
{ //list is empty, so update the tail
tail = NULL;
}
}
//removeFromTail function:
void LinkedList::removeFromTail()
{
Node* temp;
temp = tail->get_prev();
if (head != NULL)
{
temp->set_next(NULL);
tail = temp;
} else
{ //list is empty, so update the head
head = NULL;
}
}
//remove function: removes a Node by a string input
void LinkedList::remove(string l)
{
//cycle through LinkedList:
for (current = head; current != NULL; current = current->get_next())
{
//check for match:
if (l == current->get_data().get_licence() && current == head)
{
removeFromHead();
} else if (l == current->get_data().get_licence() && current == tail)
{
removeFromTail();
} else if (l == current->get_data().get_licence())
{
//delete the node
removeByNode(current);
} else
{
//do nothing, move on to next iteration of for loop
}
}
}
//removeByNode function:
//Preconditions: input c points to a node to be removed
//Postconditions: the node pointed to by c before is now gone. current now points to head
void LinkedList::removeByNode(Node* c)
{
current = c;
current->get_prev()->set_next(current->get_next());
current->get_next()->set_prev(current->get_prev());
delete current;
current = head;
}
//search function:
bool LinkedList::search(const Node::value_type& target)
{
for (current = head; current != NULL; current = current->get_next())
{
if (target == current->get_data())
{
return true;
}
}
//else:
return false;
}
// += operator overload (new):
LinkedList LinkedList::operator += (const LinkedList& LL2)
{
LinkedList* t = this;
Node* temp = LL2.head;
while (temp != NULL)
{
t->addToTail(temp->get_data());
temp = temp->get_next();
}
return *t;
}
// -= operator overload:
LinkedList LinkedList::operator -= (const LinkedList& LL2)
{
LinkedList* t = this;
Node* temp1;
Node* temp2;
//Cycle through LL2:
for (temp2 = LL2.head; temp2 != NULL; temp2 = temp2->get_next())
{
//Cycle through LL1:
for (temp1 = t->head; temp1 != NULL; temp1 = temp1->get_next())
{
//Check if current of LL1 has a match in LL2:
if (temp1->get_data() == temp2->get_data())
{
t->removeByNode(temp1);
}
}
}
return *t;
}
-= operator overload (within LinkedList.cpp, just putting it here under new heading for easy location):
// -= operator overload:
LinkedList LinkedList::operator -= (const LinkedList& LL2)
{
LinkedList* t = this;
Node* temp1;
Node* temp2;
//Cycle through LL2:
for (temp2 = LL2.head; temp2 != NULL; temp2 = temp2->get_next())
{
//Cycle through LL1:
for (temp1 = t->head; temp1 != NULL; temp1 = temp1->get_next())
{
//Check if current of LL1 has a match in LL2:
if (temp1->get_data() == temp2->get_data())
{
t->removeByNode(temp1);
}
}
}
return *t;
}
-= operator call within another 'main()' program:
LinkedList tollBooth1;
LinkedList tollBooth2;
LinkedList dailyReport;
//(add data to tollBooth 1 and 2, merge these 2 objects into dailyReport)
//removing the contents of both booths from daily report:
dailyReport -= tollBooth1;
dailyReport -= tollBooth2;
You've included way too much code. The general ask on this site is to provide a minimal reproducible example.
Problems
I have no idea why you have a member variable named current. It often points to deleted memory.
You need to implement the "rule of three" or the "rule of five" on your LinkedList class. If you copy the LinkedList, and then modify it, you will have dangling pointers.
LinkedList a;
LinkedList b = a;
a.RemoveHead();
// b.head is now pointing to deleted memory.
LinkedList::removeByNode(Node* c) does not update the head and tail member variables if the removed node was the head or tail respectively.
Your operator-= uses temp1 after it has been deleted.
There are likely more issues.
I implemented a linked list in a class with addToHead, addToTail, deleteFromHead, deleteFromTail, isEmpty, and display functions, and I want to sort the linked list in ascending order in an inherited class, so I made a class TSortedList with two functions; the sortList function that compares the elements of the linked list with each other, and the display() function that display the linked list after sorting it. But when I run the code nothing appear to me, however when I sort it through a function in the parent class, not the inherited class it works, so I do not know where is the problem
#include <iostream>
using namespace std;
class Node {
public:
Node() {
next = 0;
//write your modification here
}
Node(int el, Node *ptr = 0) { //write your modification for the constructor arguments here
info = el;
next = ptr;
}
int info;
Node *next;
//write your modification here
};
class LList {
protected:
Node *head, *tail;
public:
LList() {
head = tail = 0;
}
~LList(){
for (Node *p; !isEmpty(); ) {
p = head->next;
delete head;
head = p;
}
}
int isEmpty() {
return head == 0;
}
virtual void addToHead(int el){
head = new Node(el,head);
if (tail == 0)
tail = head;
}
virtual void addToTail(int el){
if (tail != 0) { // if list not empty;
tail->next = new Node(el);
}
else head = tail = new Node(el);
}
int deleteFromHead(){ // delete the head and return its info;
int el = head->info;
Node *tmp = head;
if (head == tail) // if only one node in the list;
head = tail = 0;
else head = head->next;
delete tmp;
return el;
}
int deleteFromTail(){ // delete the tail and return its info;
int el = tail->info;
if (head == tail) { // if only one node in the list;
delete head;
head = tail = 0;
}
else { // if more than one node in the list,
Node *tmp; // find the predecessor of tail;
for (tmp = head; tmp->next != tail; tmp = tmp->next);
delete tail;
tail = tmp; // the predecessor of tail becomes tail;
tail->next = 0;
}
return el;
}
bool isInList(int el) const{
Node *tmp;
for (tmp = head; tmp != 0 && !(tmp->info == el); tmp = tmp->next);
return tmp != 0;
}
virtual void displayList(){
if (head == 0) // if empty list;
return;
Node *tmp = head;
for (tmp = head; tmp != 0; tmp = tmp->next){
cout<<tmp->info<<endl;
}
}
};
class TSortedList: public LList, public Node
{
protected:
Node *current = head, *index = 0;
int temp;
public:
void sortList() {
if(head == 0) {
return;
}
else {
while(current != 0) {
//Node index will point to node next to current
index = current->next;
while(index != 0) {
//If current node's data is greater than index's node data, swap the data betweenthem
if(current->info > index->info) {
temp = current->info;
current->info = index->info;
index->info = temp;
}
index = index->next;
}
current = current->next;
}
}
}
void display() {
//Node current will point to head
Node *current = head;
if(head == 0) {
return;
}
while(current != 0) {
//Prints each node by incrementing pointer
cout<<current->info<<endl;
current = current->next;
}
cout<<"\n"<<endl;
}
};
int main()
{
//Adds data to the list
LList myList;
myList.addToHead(1);
myList.addToHead(7);
myList.addToHead(3);
TSortedList sortt;
sortt.sortList();
sortt.display();
return 0;
}
Your TSortedList sortt; is empty; you never add anything to it.
What do you expect it to display?
This should work as you expected:
int main()
{
//Adds data to the list
TSortedList myList;
myList.addToHead(1);
myList.addToHead(7);
myList.addToHead(3);
myList.display(); // this should be in original order
myList.sortList();
myList.display(); // this should be sorted
return 0;
}
Also, why are you deriving your TSortedList from Node?
class TSortedList: public LList, public Node
So basically I created a linked list with the append and prepend functions and when I print the list it is only printing out 12 which I prepended to front of the list and not the other elements, how do I fix this issue? so that all the elements will be printed. I think that my append and prepend functions are correct but I do not know what could be wrong.
#include <iostream>
#include "List.h"
using namespace std;
int main() {
List* list = new List();
list->Append(1);
list->Append(2423);
list->Prepend(12);
list->print();
system("pause");
return 0;
}
#include<iostream>
#include "List.h"
using namespace std;
List::List() {
this->HEAD = NULL;
this->TAIL=NULL;
}
void List::Append(int Data_val) {
NODE* Current = new NODE;
Current->data = Data_val;
if (HEAD == NULL) {
HEAD = Current;
TAIL = Current;
Current->next = nullptr;
}
else {
TAIL->next= Current;
TAIL = Current;
Current->next = nullptr;
}
}
void List::Prepend(int data_val) {
NODE* Current = new NODE;
Current->data = data_val;
if (HEAD = NULL) {
Current->next = nullptr;
HEAD = Current;
TAIL = Current;
}
else {
Current->next = HEAD;
HEAD = Current;
Current->next = nullptr;
}
}
void List::print() {
NODE* Current = HEAD;
while (Current != NULL) {
cout << Current->data << endl;
Current=Current->next;
}
}
#ifndef LIST_H
#define LIST_H
struct NODE {
int data;
NODE* next;
};
class List
{
public:
List();
void Append(int data_val);
void Prepend(int data_val);
//create prepend
//create insertafter
//create delte
void print();
private:
//
NODE * HEAD;
NODE* TAIL;
};
#endif
You havae a bug with your List::Prepand() method. The "Current->next = nullptr;"
line is not needed within "else" block.
void List::Prepend(int data_val) {
NODE* Current = new NODE;
Current->data = data_val;
if (HEAD == NULL) {
Current->next = nullptr;
HEAD = TAIL = Current;
}
else {
Current->next = HEAD;
HEAD = Current;
Current->next = nullptr; // <---- remove this line
}
}
Header File:
#ifndef LL_H
#define LL_H
// include this library to use NULL, otherwise use nullptr instead
#include <cstddef>
// include iostream so anything that includes this file can use cout
#include <iostream>
// Struct which will be the building block of our list
struct node
{
int val;
node* next;
};
// Contents of 11.h
// Linked list class definition
class LL
{
public:
LL();
bool removeFront();
bool removeBack();
node* search(int);
void print();
private:
node* head;
};
#endif
Source File:
#include "ll.h"
LL::LL()
{
head = NULL;
}
void LL::search (int num)//heading of the function
{
node* newNode = new node;
newNode->val = num;
newNode->next = NULL;
while (newNode == NULL)
{
if (newNode->val == num)
{
return newNode;
}
newNode = newNode->next; //point to the next node
}
return; //not sure if needed
}
The program will read in a
text file called “cmd.txt” that will instruct what operations to run. our program should implement a C++ class which will be used to represent the linked list.
Search should look more like:
node* LL::Search(int num)
{
node* current = head;
while (current != null)
{
if (current->val == num)
{
return current;
}
current = current->next;
}
return null;
}
This is the correct format
node* LL::search(int num)
{
node* newNode = new node;
newNode = head;
while (newNode->next != NULL)
{
if (newNode->val == num)
{
return newNode;
}
newNode = newNode->next;
}
return NULL;
}
The removeNode() function implements a circular doubly linked list which has a sentinel node. What I am trying to do is defined in pseudo code next to the function. I simply just am having a hard time understanding how to do so.
#include "CDLList.h"
#include <iostream>
using namespace std;
ListNode *createList()
{
ListNode *sentinel = new ListNode();
sentinel->last = sentinel;
sentinel->next = sentinel;
return sentinel;
}
void destroyList(ListNode *&sentinel)
{
// Delete any item nodes
clearList(sentinel);
// Delete the sentinel node
delete sentinel;
sentinel = nullptr;
}
bool isEmpty(ListNode *sentinel)
{
return (sentinel == sentinel->next);
}
ListNode *findNode(ListNode *sentinel, string value)
{
ListNode *pCurrNode = sentinel->next;
while (pCurrNode != sentinel)
{
// Check if we found the node
if (pCurrNode->item == value)
{
return pCurrNode;
}
// Move to next node
pCurrNode = pCurrNode->next;
}
return nullptr;
}
void addItem(ListNode *sentinel, string value)
{
ListNode *newNode = new ListNode;
newNode->item = value;
newNode->last = sentinel->last;
newNode->next = sentinel;
sentinel->last->next = newNode;
sentinel->last = newNode;
}
void removeNode(ListNode *node) // Implement this function!
{
// Unlink node
// Delete node
}
The removeNode() function is called within these two functions
void removeItem(ListNode *sentinel, string value)
{
ListNode *node = findNode(sentinel, value);
// If the item was not found, there's nothing to do (remove)
if (node == nullptr)
{
return;
}
removeNode(node);
}
void clearList(ListNode *sentinel)
{
while (!isEmpty(sentinel))
{
removeNode(sentinel->next);
}
}
Here's the function implementation:
void removeNode(ListNode *node)
{
if(!isEmpty(node))
{
ListNode* nodeLast = node->last;
ListNode* nodeNext = node->next;
// Unlink node
nodeLast->next = nodeNext;
nodeNext->last = nodeLast;
}
// Delete node
delete node;
}