Reputation: 305
Im creating my own doubly linked list program (I know there is a list library). I have my main.cc with just my main function that provides a menu to choose the various options for my program and call the correct functions/objects. I then have 3 different header files containing class files, 1 is the general file for my doubly linked list functions, another is to turn the general DLL functions into queue functions and the last one is to convert the DLL functions to stack functions.
main.cc
#include <iostream>
#include "doubly-linked-list.h"
#include "DLLstack.h"
#include "DLLqueue.h"
using namespace std
int choice=0,choice2=0;
int main()
{
int choice=0,choice2=0,i=0;
DoublyLinkedList<int> lst;
DLLstack stlist;
while(1)
{
choice2=0;
//ask user
cout<<"\n1. Create Simple (Unsorted) List\n2. Create Sorted List\n";
cout<<"3. Create LIFO Queue\n4. Create FIFO Queue(Stack)\n";
cout<<"5. Exit Program\n";
cout<<"Please choose an option\n";
cin>>choice;
while(choice==1)
{
//ask user 1.a
cout<<"\n1. Enter integer for insertion at head of list\n2. Enter integer for insertion at tail of list\n";
cout<<"3. Display and Delete integer at head\n4. Display and Delete integer at tail\n";
cout<<"5. Search for integer in list and delete that node\n6. Display Contents of list from head to tail in order\n7. Exit\n";
cout<<"Please choose an option\n";
cin>>choice2;
if(choice2==1)//1.1
{cout<<"Enter integer to add to head\n";
cin>>i;
lst.addToDLLHead(i);
}
if(choice2==2)//1.2
{
cout<<"Enter integer to add to tail\n";
cin>>i;
lst.addToDLLTail(i);
}
if(choice2==3)//1.3
{ try{
i=lst.deleteFromDLLHead ();
} catch(int error_code)
{
cerr<<"Error: "<<error_code<<endl;
switch(error_code)
{cout<<"Empty List\n";
return(1);
}
}
cout<<"The deleted int was "<<i<<endl;
}
if(choice2==4)//1.4
{ try{
i=lst.deleteFromDLLTail ();
} catch(int error_code)
{
cerr<<"Error: "<<error_code<<endl;
switch(error_code)
{case 1:
cout<<"Empty List\n";
return(1);
}
}
cout<<"The deleted int was "<<i<<endl;
}
if(choice2==5)//1.5
{
cout<<"Enter Integer to search for and delete"<<endl;
cin>>i;
try{
lst.searchdelete (i);
} catch(int error_code)
{
cerr<<"Error: "<<error_code<<endl;
switch(error_code)
{cout<<"Empty List\n";
return(1);
}
}
}
if(choice2==6)
{lst.printlist ();}
if(choice2==7) choice=0;
}
while(choice==2)
{
//ask user 2.b
cout<<"\n1. Enter integer for sorted insertion(increasing order) into list\n2. Display and delete integer if present in list\n";
cout<<"3. Display contents of sorted list of integers, in increasing order\n";
cout<<"4. Exit program\n";
cout<<"Please choose an option\n";
cin>>choice2;
if(choice2==1)//2.1
{cout<<"Enter integer to add to the sorted list"<<endl;
cin>>i;
lst.addSorted (i);
}
if(choice2==2)
{
cout<<"Enter Integer to search for and delete"<<endl;
cin>>i;
try{
lst.searchdelete (i);
} catch(int error_code)
{
cerr<<"Error: "<<error_code<<endl;
switch(error_code)
{cout<<"Empty List\n";
return(1);
}
}
}
if(choice2==3)
{lst.printlist ();}
if(choice2=4)
{choice=0;}
}
while(choice==3)
{
cout<<"\n1. ENQUEUE\n2. DEQUEUE\n";
cout<<"3. Print QUEUE\n";
cout<<"4. Exit program\n";
cout<<"Please choose an option\n";
cin>>choice2;
DLLQueue.qlst;
if(choice2==1)
{
cout<<"Enter number to place in Queue"<<endl;
cin>>i;
qlst.enqueue(i);}
if(choice2=2)
{try{qlst.dequeue();
} catch(int error_code)
{
cerr<<"Error: "<<error_code<<endl;
switch(error_code)
{cout<<"Empty List\n";
return(1);
}
}
}
if(choice2=3)
{lst.printlist ();}
if(choice2=4)
{choice=0;}
}
while(choice==4)
{
cout<<"\n1. Push\n2. Pop\n";
cout<<"3. Print STACK\n";
cout<<"4. Exit program\n";
cout<<"Please choose an option\n";
cin>>choice2;
if(choice2==1)
{cout<<"Please enter value to place in stack"<<endl;
cin>>i;
stlst.push(i);
}
if(choice2==2)
{stlst.pop();}
if(choice2==3)
{lst.printlist ();}
if(choice2==4)
{choice=0;}
}
} //original while
return 0;
}
doubly-linked-list.h
#ifndef DOUBLY_LINKED_LIST
#define DOUBLY_LINKED_LIST
#include <iostream>
using namespace std;
const int EMPTY_LIST=1;
template<class T>
class DLLNode
{
friend class DoublyLinkedList;
friend class DLLQueue;
friend class DLLstack;
public:
DLLNode(){next=prev=NULL;}
DLLNode(const T& el, DLLNode *n=NULL, DLLNode *p=NULL)
{info=el;
next=n;
prev=p;
}
T info;
DLLNode<T> *next, *prev;
protected:
//T info;
//DLLNode<T> *next, *prev;
private:
};
template<class T>
class DoublyLinkedList
{
friend class DLLQueue;
friend class DLLstack;
public:
DoublyLinkedList() {head=tail=NULL;} //good
void addToDLLTail(const T&); //good
T deleteFromDLLTail(); //good
T isDLLEmpty() {return (head==NULL);} //good
void addToDLLHead(const T&); //added
T deleteFromDLLHead(); //added
void deleteDLLNode(const T&); //added
bool isInList(const T&) const; //added
void addSorted(const T&); //added
void printlist(); //added
T searchdelete(const T&);
protected:
private:
DLLNode<T> *head, *tail;
};
template<class T>
T DoublyLinkedList<T>::deleteFromDLLTail(){
if(head!=NULL){
T el=tail->info;
if(head==tail){
delete tail;
head=tail=NULL;
}
return el;
}
else throw(EMPTY_LIST);
}
template<class T>
void DoublyLinkedList<T>::addToDLLTail(const T& el) {
if(tail!=NULL){
tail=new DLLNode<T>(el,NULL,tail);
tail->prev->next=tail;
}
else head=tail= new DLLNode<T>(el);
}
template<class T>
void DoublyLinkedList<T>::addToDLLHead (const T& el) {
head = new DLLNode<T>(el,head);
if(tail==NULL) tail=head;
}
template<class T>
T DoublyLinkedList<T>::deleteFromDLLHead (){
if(head!=NULL)
{
int el=head->info;
DLLNode<T> *tmp=head;
if(head==tail)
{head=tail=NULL;}
else{head=head->next;}
delete tmp;
return(el);
}
else throw(EMPTY_LIST);
}
template<class T>
void DoublyLinkedList<T>::deleteDLLNode(const T& el) {
if(head!=NULL){
if(head==tail&&el==head->info) {
delete head;
head=tail=NULL;
}
else if(el==head->info){
DLLNode<T> *tmp=head;
head=head->next;
head->prev=NULL;
delete tmp;
}
else {
DLLNode<T> *pred, *tmp;
for(tmp=head->next;tmp!=NULL && tmp->info!=el;tmp=tmp->next);
if(tmp!=NULL){
pred=tmp->prev;
pred->next=tmp->next;
pred->next->prev=pred;
if(tmp==tail) {tail=tail->prev;}
delete tmp;
}
}
}
else throw(EMPTY_LIST);
}
template<class T>
bool DoublyLinkedList<T>::isInList(const T& el) const {
DLLNode<T> *tmp;
for(tmp=head;tmp!=NULL&&tmp->info !=el; tmp=tmp->next);
return (tmp !=NULL);
}
template<class T>
void DoublyLinkedList<T>::addSorted(const T& i) {
DLLNode<T> *tmp, *nxt;
for(tmp=head;tmp->info<i;tmp=tmp->next);
nxt=tmp->next;
tmp->next= new DLLNode<T> (i,nxt,tmp);
next->prev=tmp->next;
delete tmp;
delete nxt;
}
template<class T>
void DoublyLinkedList<T>::printlist() {
DLLNode<T> *tmp;
if(head!=NULL){
for(tmp=head;tmp->next!=NULL;tmp=tmp->next){
cout<<tmp->info<<endl;
}
}
}
template<class T>
T DoublyLinkedList<T>::searchdelete(const T& i)
{ DLLNode<T> *tmp;
for(;tmp->info!=i&&tmp!=NULL;tmp=tmp->next){}
delete DLLNode<T> (tmp);
return(cout<<"Value Deleted from List\n");
}
#endif // DOUBLY_LINKED_LIST
DLLstack.h
#ifndef _DLLSTACK_H_
#define _DLLSTACK_H_
#include <iostream>
using namespace std;
#include "doubly-linked-list.h"
class DLLstack
{
friend class<class T> DoublyLinkedList;
friend class<class T> DLLNode;
public:
DLLstack(){};
bool isEmpty() const
{return lst.isEmpty();}
void clear()
{
while(!list.isEmpty()){
lst.deleteFromDLLHead();}
}
int pop()
{return (lst.deleteFromHead();}
void push(const int& el);
{lst.addToDLLHead (el);}
int topEl()
{
int topelement;
topelement=lst.deleteFromDLLHead ();
lst.addToDLLHead (topelement);
return(topelement);
}
protected:
private:
DoublyLinkedList stlst;
};
#endif // _DLLSTACK_H_
DLLqueue.h
#ifndef _DLLQUEUE_H_
#define _DLLQUEUE_H_
#include <iostream>
using namespace std;
#include "doubly-linked-list.h"
template<class T>
class DLLQueue
{
friend <class T> class DoublyLinkedList
friend <class T> class DLLNode
public:
DLLQueue(){};
bool isEmpty() const
{ return lst.isEmpty();}
void enqueue(const T& el)
{ lst.addToDLLTail (el);}
T dequeue()
{ return {lst.deleteFromDLLHead ();}
T firstEl()
{
T front_el;
front_el=lst.deleteFromDLLHead ();
lst.addToDLLHead (front_el);
return(front_el);
}
~DLLQueue() {clear();}
protected:
private:
DoublyLinkedList qlst;
};
#endif // _DLLQUEUE_H_
Now I get 30 errors, but my main problem (i think) is that it says my friend function declarations in my DLLqueue.h file and DLLstack.h file are DLLqueue.h:11:9: error: expected unqualified-id before ‘<’ token DLLstack.h:11:14: error: expected identifier before ‘<’ token
as well as my lst object in both the stack and queue classes "was not declared in this scope"
doubly-linked-list.h:141:2: error: ‘next’ was not declared in this scope
there are more errors but I think these are causing the major problems and i need to fix these first to continue.
If you are wondering I am programming in the Ajuta IDE in Ubuntu
Upvotes: 0
Views: 1561
Reputation: 254431
friend <class T> class DoublyLinkedList
should be
template <class U> friend class DoublyLinkedList;
or
friend class DoublyLinkedList<T>;
depending on which instantiations actually need to be friends; and likewise for the other friend declarations.
DoublyLinkedList qlst;
should be
DoublyLinkedList<T> qlst;
since DoublyLinkedList
is a template, not a type.
There's shouldn't be a semicolon before the function body in DLLStack::push
:
void push(const int& el);
{lst.addToDLLHead (el);}
You have an unwanted (
with no matching )
in DLLstack::pop
:
{return (lst.deleteFromDLLHead();}
And an unwanted {
in DLLQueue::deque
:
{ return {lst.deleteFromDLLHead ();}
There are various typos (e.g. declaring a member stlst
and referring to it variously as lst
and list
) - the compiler errors will point you directly at these.
DoublyLinkedList::isDLLEmpty
needs to be declared const
, so it can be called from the const
member functions of the other classes (once you've fixed the typos that call it isEmpty
).
In DoublyLinkedList::searchdelete
, delete DLLNode<T>(tmp)
should just be delete tmp
. You also need to fix up the pointers in the nodes on either side of the deleted one, and return a value of type T
(presumably i
), and fix the behaviour of the loop so it actually searches for the correct node (as it is, it iterates through to the end, then deletes the null pointer, with the result that it does nothing).
Finally, ~DLLQueue
tries to call DoublyLinkedList::clear
which doesn't exist. You should implement either that, or a destructor for DoublyLinkedList
(or both). As it is, the list is a memory leak. It should also have a copy constructor and assignment operator (simply declared private if you don't want the class to be copyable).
Also, you shouldn't use reserved names (beginning with an underscore, such as _DLLQUEUE_H_
) as include guards. You also shouldn't put using namespace std;
in your header files; the user of the header file might not want the global namespace polluted.
Upvotes: 2
Reputation: 129764
std::deque
with std::stack
and std::queue
adaptors instead.using namespace std
in the header.template <typename T> friend class X;
(or with class
instead of typename
). Also, identifiers are case sensitive, DLLStack
and DLLstack
are two completely different things.std::exception
instead.I don't see any more major problems, but I might be missing something in all the pointer stuff.
Upvotes: 0
Reputation: 24403
Change your friend declaration to
template <class U> friend class DLLNode;
Also semicolons are missing here
class DLLQueue
{
friend <class T> class DoublyLinkedList
friend <class T> class DLLNode
Upvotes: 1