Print a Doubly Linked List in Reverse - c++

I have a list that is dynamically created based off of user input. I can add strings, and I can remove strings, but I am at a loss on how to properly print this in reverse.
Example:
input : First Second Last
output: Last Second First
I have tried a few things, and I have looked up what needs to be done, but I am having a tough time getting it correct.
#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std;
// define a node for storage and linking
class node{
public:
string name;
node *next;
node *prev;
};
class linkedList{
public:
linkedList() :top(NULL){}
bool empty(){ return top == NULL; }
node *getTop(){ return top; }
void setTop(node *n){ top = n; }
void add(string);
int menu();
void remove(string);
~linkedList();
void reversePrint();
friend ostream& operator << (ostream&, const linkedList&); // default
output is in-order print.
private:
node *top;
node *end;
};
void main(){
linkedList l;
cout << l.empty() << endl;
int option = 0;
string s;
bool go = true;
while (go){
option = l.menu();
switch (option){
case 1: cout << "enter a name: "; cin >> s; l.add(s); break;
case 2: cout << "enter name to be deleted: "; cin >> s; l.remove(s); break;
case 3: cout << l; break;
case 4: cout << l.reversePrint(); break; // I am getting a Syntax error here
case 5: cout << "exiting" << endl; go = false; break;
}
}
system("PAUSE");
// l goes out of scope and calls ~linkedList()
}
void linkedList::reversePrint()
{
node *start_ptr = NULL;
node *current = start_ptr;
node *prev = NULL;
node *next = NULL;
while (current){
next = current->next;
current->next = prev;
current->prev = next;
prev = current;
current = next;
}
}

You didn't provide complete code (such as the implementation of linkedList::add()) so it's hard to give the correct answer...
According to your partial code, since the return type of reversePrint() is void, you can not cout it.
Therefore, in the switch block in main function should be:
case 4: l.reversePrint(); break;
I try to modify your code but not sure if it's correct since I don't have the code.
void linkedList::reversePrint()
{
node *current = end;
while (current){
cout << current->name << " ";
current = current->prev;
}
}

Related

C++ Making functions not accessed by the client private

Here is Main.cpp:
#include <iostream>
#include <cstdlib>
#include "linklist.h"
using namespace std;
void menu(List &);
int main()
{
//new list
List list;
menu(list);
return 0;
}
void menu(List &list)
{
char choice;
int item;
do {
system("CLS"); // for ise of std library
cout<<"\t Menu\n";
cout<<"\t\tOptions\n\n";
cout<<"\t\tInsert a Student (press I)\n";
cout<<"\t\tRemove a Student (press R)\n";
cout<<"\t\tDisplay List of Student (press D)\n";
cout<<"\t\tClear List (press C)\n";
cout<<"\t\tExit (press E)\n";
cout<<"What would you like to do ? Press the coresponding key:";
cin>>choice;
choice = toupper(choice);
cin.ignore();
switch(choice)
{
case 'I':
list.Insert();
break;
case 'R':
list.Remove();
break;
case 'D':
list.Display();cin.get();
break;
case 'C':
list.Clear();cin.get();
break;
}
Here is list.cpp
#include "linklist.h"
#include <iostream>
using namespace std;
// insert at begining of the linked list
void List::Insert()
{
int student_id;
short test_one,test_two;
float average;
cout << "Enter the Student's ID: "; cin >> student_id;
cout << "Enter the score of Test One: "; cin>> test_one;
cout << "Enter the score of Test Two: "; cin >> test_two;
average = (test_one + (double)test_two)/2;
// new node
Node* newnode = new Node();
newnode->setnode(student_id,test_one,test_two,average);
newnode->setnext(head);
head = newnode;
}
// deletes from the last node in the list
void List::Remove()
{
Node* curr = head;
if (curr = NULL) {
cout << "No nodes to remove\n ";
return;
}
else if (curr->getnext() == NULL ) // it only has 1 !
{
delete curr;
head = NULL;
}
else
{
Node *prev;
do
{
prev = curr; // the prev becomes the curr
curr = curr->getnext();
}while(curr->getnext() != NULL); // while the next one is not empty
prev->setnext(NULL);
delete curr; // delte the curr and it will repeat as prev becomes curr
// unill curr=NULL
}
}
// displays the nodes to the console
void List::Display()
{
Print(head);
}
void List::Print(Node* temp)
{
if (temp = NULL)
{
cout << "End" << endl;
return;
}else
{
temp->getnode();
Print(temp->getnext()); // these two steps will continue
} // until temp=NULL
}
// clears the linked list of all nodes
void List::Clear()
{
Node *temp = head; //store current head in temp
while(head != NULL)
{
head = head->getnext(); // set next head to head
delete temp; // delete current head in temp
}
}
Here is header file for the node class with functions:
#ifndef NODE_H
#define HODE_H
#include <iostream>
using namespace std;
// Here is the node class
class Node {
int student_id;
short test_one;
short test_two;
float average;
Node* next;
public:
Node(){}
void setnode(int student_id,short test_one,short test_two,float average)
{
student_id = student_id;
test_one = test_one;
test_two = test_two;
average = average;
}
void setnext(Node *link)
{
next = link;
}
void getnode( )const
{
cout << "The student's ID #: " << student_id << endl;
cout << "Score of Test One: " << test_one << endl;
cout << "Score of Test Two: " << test_two << endl;
cout << "The average: " << average << endl;
}
// returns address of the next node
Node* getnext()
{
return next;
}
};
#endif
Here is the header file for the class
#include "node.h"
#include <iostream>
class List
{
Node *head;
public:
List()
{
head = NULL;
}
void Insert();
void Remove();
void Clear();
void Display();
void Print(Node*);
};
Now what has to be done is a refactor of the following code so that:
"functions that are not accessed by the client should be private, mutator functions parameters are constant referenced, and all accessor functions are constants."
I've tired just switching to private, I've tried creating friends, and I have read something about runtime polymorphism and didn't try to implement because it did not seem to apply. I don't know where to start now because I'm under the impression that main.cpp is the client and it has to have access in order for this to work.
How would the above refactor ("functions that are not accessed by the client should be private, mutator functions parameters are constant referenced, and all accessor functions are constants.") work/look ?
After reading some of the comments and some more research. I've decided that setnode, getnode, getnext, setnext and Print should be private. They do not need any interaction with a user. Or I should say, that a user can incorrectly input parameters.
How about pass by reference ?
I'm starting to refactor but I'm still getting error's that the functions are private. Can anyone show a code snippet to refactor one of (or all that should be private) the functions to private so it works when its called by main.cpp ?

Creating Linked list insertion function but the code is not running

Unable to recognize the error in creating a linked list insertion function in linked list class the compiler giving this " error: qualified-id in declaration before '(' token But it seems like all the parenthesis are placed correctly.
#include <iostream>
using namespace std;
void additem();
void deleteitem();
void searchitem(int x);
struct student{
int data;
int * next;
};
student * head;
student * curr;
int main()
{
int x;
cout << "To add item type 1" << endl;
cin >> x;
switch(x)
{
case 1:
additem();
}
return 0;
}
void additem()
{
student * temp;
if(head == NULL)
{
temp = new student;
head = temp;
curr = temp;
temp->next = NULL;
cout << "Enter data" << endl;
cin >> temp->data << endl;
}
else if(head != NULL)
{
temp = new student;
curr->next = temp;
curr = temp;
temp->next = NULL;
cout << "Enter data" << endl;
cin >> temp->data ;
}
else{
break;
}
}
You're declaring a class and methods within main. This is not allowed (nested functions). linkedlist::additem needs to be defined before main.

Implement a linked list program with the following functions

i am trying to implement a linked list with add, search, remove and print functions. But i keep getting errors that "search, print and file are not declared in this scope" and ISO C++ forbids comparison between pointer and integer [-fpermissive] error. Any help would be appreciated.
#include <iostream>
#include <stdio.h>
#include <string>
using namespace std;
struct node
{
public:
char name;
node *next;
};
bool isEmpty(node *head);
char welcomeScreen();
void addInitialElement(node *head, node*last, char name);
void add (node *&head, node *&last, char name);
void serach (node *current);
void remove (node *&head, node *&last);
void printFile(node *current);
bool isEmpty(node *head)
{
if(head == NULL)
return true;
else
return false;
}
char welcomeScreen()
{
char options;
cout <<"Address Book \n";
cout <<"Available Commands \n";
cout <<" add <name>. \n";
cout <<" search <name>. \n";
cout <<" remove <name>. \n";
cout <<" print \n";
cout <<" file <filename>. \n";
cout <<" quit \n";
cin >> options;
return options;
}
void addInitialElement(node *head, node*last, char name)
{
node *temp = new node;
temp->name = name;
temp->next = NULL;
head = temp;
last = temp;
}
void add (node *&head, node *&last, char name)
{
if(isEmpty(head))
addInitialElement(head, last,name);
else
{
node *temp = new node;
temp->name = name;
temp->next = NULL;
last->next = temp;
last = temp;
}
}
void serach (node *current)
{
node *temp = new node;
if (current->name == temp)
{
cout << "The List Contains the Following: \n";
while(current != NULL)
{
cout<< current->name <<endl;
current = current->next;
}
}
}
void remove (node *&head, node *&last)
{
if(isEmpty(head))
cout << "ERROR: Not found for Removal. \n";
else if(head == last)
{
delete head;
head == NULL;
last == NULL;
}
else
{
node *temp = head;
head = head->next;
delete temp;
}
}
void printFile(node *current)
{
if(isEmpty(current))
cout << "NO NAME IN LIST. \n";
else
{
cout << "The List Contains the Following: \n";
while(current != NULL)
{
cout<< current->name <<endl;
current = current->next;
}
}
}
int main()
{
node *head = NULL;
node *last = NULL;
char options;
char name;
do{
options = welcomeScreen();
switch(options)
{
case '1': cout <<"please add a name: ";
cin >> name;
add(head, last, name);
break;
case '2' : search(head, last);
cin >> name;
break;
case '3' : remove(head, last);
break;
case '4' : print(head);
break;
case '5' : file(head);
break;
default: cout << "system exit \n";
}
}while(options != '6');
}
You misspelled search. Do a find / replace on "serach".
In case 4, you may mean to call printFile instead of print
case '4' : printFile(head);
In case 5, I don't know what your intention is here, but there is no function called "file". Try searching on that word, file, and you'll see.

project.exe has triggered a breakpoint

I had a circular link list which has add, delete, printlist and search functions etc. All the functions works correctly but when I delete all nodes in the list and than try to add new nodes to the same list, I get project.exe has triggered a breakpoint message.
List.h
#ifndef LIST_H
#define LIST_H
using namespace std;
class list {
public:
struct node {
string data, assignee, date;
node *next;
};
typedef struct node NodePtr;
NodePtr *head, *current, *temp, *dummy;
list();
void add();
void del();
void printList();
void menu();
void exit();
void search();
};
#endif
Source.cpp
#include <cstdlib>
#include <iostream>
#include "List.h"
#include<string>
using namespace std;
list::list() { //constructor
head = NULL;
current = NULL;
temp = NULL;
}
void list::add(){
string addTask, addAssignee, addDate;
NodePtr *newNode = new NodePtr;
//entering the data of the tasks
cout << "Enter the name of the task:\n"<<"<<";
getline(cin, addTask); // compailer doesnt detect the first getline function, ı dont understan why. ı had to put it twice
getline(cin, addTask);
cout << "Enter the assignee name for the task:\n" << "<<";
getline(cin, addAssignee);
cout << "Enter the deadline for the task:\n" << "<<";
getline(cin, addDate);
cout << "\n";
//assignt data to the new node
newNode->data = addTask;
newNode->assignee = addAssignee;
newNode->date = addDate;
newNode->next = NULL;
if (head != NULL){
current = head;
while (current->next != head){ //finding the last node
current = current->next;
}
current->next = newNode;
dummy = newNode;
dummy->next = head; // we make the list, circular
}
else //here will work if the list is empty
{
head = newNode;
dummy = newNode;
head->next=head;
}
}
void list::printList(){
int i = 1;
current = head;
if (head == NULL){
cout << "List is empty\n\n";
}
else
{
do
{
cout << i << "-";
cout << current->data << endl;
cout << current->assignee << endl;
cout << current->date << endl << endl;
current = current->next;
i++;
} while (current != dummy->next);
}
}
void list::del(){ //tüm liste silindikten sonra tekrar işlem(ekleme, listeleme etc.) yapılamıyor hata veriyor
NodePtr *delPtr;
delPtr = NULL;
int ID;
cout << "These tasks exist in the list:\n";
printList();
cout << "Choose the ID of the task you want to remove:\n";
cin >> ID;
if (head == NULL){
cout << "List does not includes any task.\n";
}
else
if (ID == 1){
delPtr = head;
head = head->next;
delete delPtr;
dummy->next = head;
}
else
{
current = head;
for (int k = 1; k <= ID - 1; k++){
temp = current;
current = current->next;
}
if (current == dummy){
dummy = temp;
dummy->next = head;
}
delPtr = current;
current = current->next;
temp->next = current;
delete delPtr;
}
}
void list::menu(){
cout << "Choose an operation\n"
<< "A: Add Task\n"
<< "S: Search for Task\n"
<< "L: List All Tasks\n"
<< "R: Remove Task\n"
<< "E: Exit\n\n"<<"<<";
}
void list::search(){
string searchTask;
NodePtr *search;
search = head;
cout << "To search for a task, enter its task name or assignee name:\n" << "<<";
getline(cin, searchTask);
getline(cin, searchTask);
while (search != dummy){//bu satır problemli gibi gözüküyor
if (search->data == searchTask || search->assignee == searchTask){
cout << search->data << endl
<< search->assignee << endl
<< search->date << endl<<endl;
}
search = search->next;
}
}
void list::exit(){
node *delPtr;
current = head;
if (head != NULL){
do{
temp = current;
delPtr = temp;
current = current->next;
delete delPtr;
} while (current != dummy);
}
}
Main.cpp
#include <cstdlib>
#include <iostream>
#include "List.h"
#include<string>
using namespace std;
int main(){
char operation;
list tasks;
tasks.menu();
cin >> operation;
while (operation!='E' && operation!='e'){
switch (operation)
{
case 'A':case'a':
tasks.add();
break;
case 'S': case's':
tasks.search();
break;
case 'L': case 'l':
cout << "All tasks are listed below:\n";
tasks.printList();
break;
case 'R': case 'r':
tasks.del();
break;
default:
break;
}
tasks.menu();
cin >> operation;
}
tasks.exit();
return 0;
}

Error in adding element to the back of linked list

I am trying to add an element to the back of a linked list.
I am able to add the element and everything works fine on the first try but when i try to add another element, the previously added element becomes rubbish value.
The problem is solved when i replace the LinkedList::process_example(int choice,LinkedList &set) function in the main menu with exactly the same code in my function declaration. Can someone explain to me why????
#include <iostream>
#include <ctime>
using namespace std;
struct Node;
typedef void* VoidPtr;
typedef Node* NodePtr;
typedef char* ZodiacSign;
const int MAX=12;
struct Node
{
NodePtr next;
VoidPtr data;
};
class LinkedList
{
public:
LinkedList();
//~LinkedList();
void Addelement(VoidPtr);
void printSet();
int compareEqual(VoidPtr,VoidPtr);
void swap(int num,int x,ZodiacSign tempSign [MAX]);
void process_example(int choice);
int check_cardinality();
void Addelementfromback(VoidPtr);
private:
NodePtr head;
ZodiacSign getVP(VoidPtr);
};
int choice=1;
LinkedList set;
do {
cout<<endl
<<endl;
cout<<"Wish to try the following operation?"
<<endl
<<"1. Add an element to set"// the function to add to back of linked list
<<endl
<<"2. Check an element in set"
<<endl
<<"3. check carinality"
<<endl
<<"9. Quit"
<<endl
<<endl;
cout<<"Your choice : ";
cin>>choice;
cin.clear();
cin.ignore(200,'\n');
set.process_example(choice);
} while (choice !=9);
void LinkedList::process_example(int choice)
{
switch (choice)
{
case 1:
cout<<endl
<<endl
<<"Current S = ";
this->printSet();
cout<<"Enter an element :";
char element [30];
cin>>element;
cin.clear();
cin.ignore(200,'\n');
this->Addelementfromback(element);
cout<<endl
<<endl
<<"Current S = ";
this->printSet();
break;
case 3:
cout<<endl
<<endl;
cout<<"Current Set S = ";
set.printSet();
cout<<endl
<<"S has ";
int count=this->check_cardinality();
cout<<count
<<" elements";
}
}
void LinkedList::printSet()
{
NodePtr temp = head;
cout<<"{ ";
while (temp != NULL)
{
cout << getVP (temp -> data) << " , ";
temp = temp -> next;
}
cout<<" } ";
cout << endl;
}
void LinkedList::Addelementfromback(VoidPtr horoscope)
{
NodePtr temp = head;
while (temp->next != NULL)
{
temp=temp->next;
}
NodePtr element = new Node;
element->data=horoscope;
element->next=NULL;
temp->next=element;
}
As WhozCraig already mentioned you need to add the following lines to the constructor
Head = NULL;
and then you can add the something like this to the beginning of function Addelementfromback
If(Head == NULL)
{
Head = new Node;
Head->data = horoscope;
Head->next = NULL;
return;
}
you also need to change the following line in LinkedList::process_example
char elements[30];
to
char* elements = new char[30];