I have a LinkedList class and everything works except for my remove function. It works except for when it is removing from the end. If I remove from the end and then try to display the new list the program crashes and doesnt give me an error. I was wondering if someone could help me pinpoint what I did wrong in the remove function where I am removing the tail.
Main method
#include "LinkedList.h"
#include <cstdlib>
#include <iomanip>
using namespace std;
void MainMenu(int& menu);
int main(int argc, char** argv) {
int menu = 0;
string name;
LinkedList list;
while (true)
{
MainMenu(menu);
if (menu == 1)
{
cout << "Please enter the name you want to add to the front: " << endl;
cin >> name;
list.addFront(name);
}
else if (menu == 2)
{
cout << "Please enter the name you want to add to the back: " << endl;
cin >> name;
list.addBack(name);
}
else if (menu == 3)
{
cout << "Please enter the name you want to remove: " << endl;
cin >> name;
list.remove(name);
}
else if (menu == 4)
{
list.display();
}
else if (menu == 5)
{
cout << "\nThank you for using my program!" << endl;
exit(0);
}
}
return 0;
}
void MainMenu(int& menu)
{
cout << '\n' << endl;
cout << left << setw(30) << right << setw(20) << "Main Menu" << endl;
cout << setw(36) << setfill('*') << "\n" << endl;
cout << "1. Add node to front." << endl;
cout << "2. Add node to back." << endl;
cout << "3. Remove node." << endl;
cout << "4. Display list." << endl;
cout << "5. Exit" << endl;
cout << setw(36) << "\n" << endl;
cout << "Please enter a menu number to proceed: " << endl;
cin >> menu;
while (menu != 1 && menu != 2 && menu != 3 && menu != 4 && menu != 5)
{
cout << "Menu options are 1 - 5" << endl;
cout << "Please enter a menu number to proceed: " << endl;
cin.clear();
cin.ignore(100, '\n');
cin >> menu;
}
cout << setfill(' ') << "\n" << endl;
}
Header file
#include <iostream>
using namespace std;
#ifndef LINKEDLIST_H
#define LINKEDLIST_H
struct Node
{
string name;
Node * next;
};
class LinkedList {
public:
Node * head = nullptr;
Node * tail = nullptr;
Node * current = nullptr;
void addFront(string name);
void addBack(string name);
void remove(string name);
void display();
LinkedList();
LinkedList(const LinkedList& orig);
virtual ~LinkedList();
private:
};
#endif /* LINKEDLIST_H */
Source File
#include "LinkedList.h"
void LinkedList::addFront(string name)
{
Node * node = new Node();
node->name = name;
if (head != nullptr)
{
node->next = head;
head = node;
}
else
{
head = node;
tail = node;
}
}
void LinkedList::addBack(string name)
{
Node * node = new Node();
node->name = name;
node->next = nullptr;
if (head == nullptr)
{
head = node;
tail = node;
}
else
{
node->next = nullptr;
tail->next = node;
tail = node;
}
}
void LinkedList::remove(string name)
{
Node * temp = head;
while (temp != nullptr)
{
if (temp->name == name)
{
cout << "Name found! Being removed." << endl;
break;
}
temp = temp->next;
if (temp == nullptr)
{
cout << "Name not found!" << endl;
return;
}
}
temp = head;
if(head == nullptr)
{
cout << "The list is empty." << endl;
return;
}
while(!(temp->name == name))
{
temp = temp->next;
}
if (temp == tail && temp == head)
{
head = nullptr;
tail = nullptr;
delete temp;
}
else if (temp == tail)
{
temp->next = tail;
delete temp->next;
temp->next = nullptr;
tail = temp;
}
else if(temp == head)
{
temp = head;
head = temp->next;
delete temp;
}
else
{
temp = head;
while(!(temp->next->name == name))
{
temp = temp->next;
}
Node * next = temp->next->next;
delete temp->next;
temp->next = next;
}
}
void LinkedList::display()
{
current = head;
if (current == nullptr)
{
cout << "The list is empty!" << endl;
}
while (current != nullptr)
{
cout << current->name << endl;
current = current->next;
}
}
LinkedList::LinkedList() {
}
LinkedList::LinkedList(const LinkedList& orig) {
}
LinkedList::~LinkedList() {
}
Your main problem is this section here
else if (temp == tail)
{
temp->next = tail;
delete temp->next;
temp->next = nullptr;
tail = temp;
}
That is what executes if the match is the last item. But if it is the last item then temp->next will be tail because you just set it to tail, and since temp == tail that also invalidates temp. Setting temp->next will be using a deleted pointer. There's no fixing this at this point because you need the previous node to set tail to, and you didn't save it, so you'd have to loop through again to get it.
Now, for the solution, you should do a single loop. No need to loop multiple times (3 in most cases)
void LinkedList::remove(string name)
{
Node * temp = head;
Node * prev = nullptr;
while (temp != nullptr)
{
if (temp->name == name)
{
cout << "Name found! Being removed." << endl;
if (prev != nullptr) {
prev->next = temp->next
}
else {
head = temp->next;
}
if (tail == temp) {
tail = prev;
}
delete temp;
return;
}
prev = temp;
temp = temp->next;
}
cout << "Name not found!" << endl;
}
For starters everywhere in member function declarations where a parameter is declared like
string name
you should change it to
const string &name
Secondly the member function remove shall not issue any message. It is the caller of the function that decides whether to output a message.
Your function is inefficient because it traverses the list two or even three times in loops and has too many conditions that makes the function too complicated. As a result the function has bugs.
For example in this if statement
else if (temp == tail)
{
temp->next = tail;
delete temp->next;
temp->next = nullptr;
tail = temp;
}
there is used deleted pointer temp to access memory because temp is equal to tail (according to the condition of the if statement)
temp->next = nullptr;
and tail again is set to the deleted pointer
tail = temp;
The function can be declared and defined the following way
class LinkedList {
public:
//...
bool remove( const std::string &name );
};
bool LinkedList::remove( const std::string &name )
{
Node *prev = nullptr;
Node *current = head;
while ( current && current->name != name )
{
prev = current;
current = current->next;
}
bool success = current != nullptr;
if ( success )
{
if ( prev )
{
prev->next = current->next;
if ( prev->next == nullptr ) tail = prev;
}
else
{
head = head->next;
if ( head == nullptr ) tail = nullptr;
}
delete current;
}
return success;
}
This question already has an answer here:
How do I properly delete nodes of linked list in C++
(1 answer)
Closed 2 years ago.
I've been asked by a friend to help him with an exercise, basically the idea is like below.
Car number = fr50000 Car owner = AlexNelson Parking time = 3.5 hours.
He was told not to use stuff like string or getline, so it's simple app just to learn the idea of working with linked lists.
So I made this program. When I'm calling the remove() function the first time, it says the list is empty at the beginning (as it should do). But the second and third time, it's saying that the car is removed, but when I call the display() function, the car is still there (it didn't remove from the list)
Can you tell me what's wrong with my code?
#include <iostream>
using namespace std;
int length = 0;//variable of how many items in the list
struct node
{
char carNumber[15];
char carOwner[20];
float parkingTime;
node *link;
};
typedef struct node node;
node *head;//the begining of a list;
bool isempty()
{
if (length == 0)
return true;
else
return false;
}
void insert()
{
if (isempty())
{
head = new node;
cout << "Enter car number: ";
cin >> head->carNumber;
cout << "Enter Car owner: ";
cin >> head->carOwner;
cout << "Enter parking time: ";
cin >> head->parkingTime;
head->link = NULL;
length++;
}
else
{
node *p = head;
node *pnext = new node;
while (true)
{
if (p->link == NULL)
{
p->link = pnext;
break;
}
p = p->link;
}
cout << "Enter car number: ";
cin >> pnext->carNumber;
cout << "Enter Car owner: ";
cin >> pnext->carOwner;
cout << "Enter parking time: ";
cin >> pnext->parkingTime;
pnext->link = NULL;
length++;
}
}
void remove()
{
if (isempty())
{
cout << "List is empty\n";
return;
}
char carnumber[15];
cout << "Enter car number to remove: ";
cin >> carnumber;
node *p;
p = head;
while (p != NULL)
{
if (strcmp(p->carNumber, carnumber) == 0)
{
p = p->link;
cout << "Car removed\n";
return;
}
p = p->link;
}
cout << "Car was not found, check the number\n";
}
void display()
{
if (isempty())
{
cout << "List is empty\n";
return;
}
cout << "Car Number\t\tCar Owner\t\tParking Time\n";
node *p = head;
while (p != NULL)
{
cout << p->carNumber << "\t\t" << p->carOwner << "\t\t" << p->parkingTime << " Hours\n";
p = p->link;
}
}
int main()
{
string number;
display();
insert();
insert();
insert();
display();
remove();
display();
insert();
remove();
display();
}
Your remove() function is not actually removing (or destroying) a node from the list. You need to update the link of the previous node in the list to point to the next node in the list. And you need to update the head too, if removing the 1st node in the list.
Try this instead:
void remove()
{
if (isempty())
{
cout << "List is empty\n";
return;
}
char carnumber[15];
cout << "Enter car number to remove: ";
cin >> carnumber;
node *p = head;
node *prev = NULL;
while (p != NULL)
{
if (strcmp(p->carNumber, carnumber) == 0)
{
if (p == head)
head = p->link;
if (prev)
prev->link = p->link;
delete p;
cout << "Car removed\n";
return;
}
prev = p;
p = p->link;
}
cout << "Car was not found, check the number\n";
}
Alternatively:
void remove()
{
if (isempty())
{
cout << "List is empty\n";
return;
}
char carnumber[15];
cout << "Enter car number to remove: ";
cin >> carnumber;
node **p = &head;
while (*p != NULL)
{
if (strcmp((*p)->carNumber, carnumber) == 0)
{
node *n = *p;
*p = (*p)->link;
delete n;
cout << "Car removed\n";
return;
}
p = &(p->link);
}
cout << "Car was not found, check the number\n";
}
p = p->link; You're modifying the value of the local variable p, not the list. You need to modify the previous node's link field.
In the loop in remove, you are doing p = p->link, when p points to the node you want to remove. But you actually need to update the link field of the node that is pointing to p.
Here's a simple way of doing that:
node **p = &head;
while(*p)
if (strcmp((*p)->carNumber, carnumber) == 0)
break;
else p = &(*p)->link;
if (*p)
{
cout<<"Car removed\n";
delete std::exchange(*p, (*p)->link);
}
else cout << "Car was not found, check the number\n";
If you can't use std::exchange, then you can replace that with:
auto h = *p;
*p = (*p)->link);
delete h;
I'm a coding newbie and I've been lost to what my program is doing. Basically, my add() method abruptly stops when I call it by case 1, 3 times, and then it terminates the program when I want to add more student ID to my node. I'm at a loss and I have been trying to find out what's wrong. Any help would be appreciated!
#include <iostream>
using namespace std;
struct Node
{
int ID;
Node *next;
}; Node *head = NULL;
void Menu();
void Add();
void Delete();
void Search();
void Display();
int main()
{
int Options = 0;
cout << "Welcome to Student Records. Choose an option:\n"
<< "1.) Add student\n"
<< "2.) Delete student\n"
<< "3.) Search student\n"
<< "4.) Display list of students\n"
<< "5.) Exit\n\n";
cout << "Input: ";
cin >> Options;
do{
switch(Options)
{
case 1:
Add();
break;
case 2:
Delete();
break;
case 3:
Search();
break;
case 4:
Display();
break;
default:
cout << "Operation terminated.";
}
cout << "\nWhat's next?\n";
Menu();
cin >> Options;
}while(Options == 1 || Options == 2 || Options == 3 || Options == 4);
cout << "Exit program?";
return 0;
}//end main
void Menu()
{
cout << "1.) Add student\n"
<< "2.) Delete student\n"
<< "3.) Search student\n"
<< "4.) Display list of students\n"
<< "5.) Exit\n\n";
}
void Add()
{
int id;
Node *node_new;
Node *pointer;
Node *lastNode = NULL;
node_new = new Node;
cout << "Enter 3-digit Student ID#: ";
cin >> id;
node_new -> ID = id;
if (head == NULL) //if list is empty
{
head = node_new;
node_new -> next = NULL;
}
else //if head is not NULL
{
pointer = head;
lastNode = NULL;
while(pointer -> ID < id && pointer != NULL)
{
lastNode = pointer;
pointer = pointer -> next;
}
if (lastNode == NULL)
{
head = node_new;
node_new -> next = pointer;
}
else
{
lastNode -> next = node_new;
node_new -> next = pointer;
}
}
}
void Delete()
{
int id;
Node *pointer;
Node *lastNode;
cout << "Enter Student ID# you wish to delete: ";
cin >> id;
if (head == NULL)
{
cout << "The list is already empty.";
}
else if (head -> ID == id)
{
pointer = head;
head = head -> next;
delete pointer;
}
else
{
pointer = head;
while(pointer -> ID != id && pointer != NULL)
{
lastNode = pointer;
pointer = pointer -> next;
}
if(pointer == NULL)
cout << "Student does not exist.";
else
lastNode -> next = pointer -> next;
delete pointer;
}
}
void Display()
{
Node *pointer;
pointer = head;
do{
if(pointer == NULL)
cout << "The list is already empty!";
else
{
cout << "Student ID# " << pointer -> ID << endl;
pointer = pointer -> next;
}
}while(pointer != NULL);
}
void Search()
{
int id;
Node *pointer;
pointer = head;
cout << "Who do you want to search? Enter ID#: ";
cin >> id;
do{
if(pointer == NULL)
cout << "Empty";
else
{
cout << "ID: " << pointer -> ID << endl;
pointer = pointer -> next;
}
}while(pointer != NULL);
}
Here is my code i have written. Whats wrong in it. Every time i delete nodes from starting to end its going fine but when deleting randomly its breaking the program.
I have to delete the nodes from the heap/memory permanently not just breaking the links between them.
#include <iostream>
using namespace std;
class Node
{
private:
int data;
Node *next;
public:
Node(){}
Node(int d)
{
data = d;
next = NULL;
}
void SetNext(Node *nextNode)
{
next = nextNode;
}
int Data()
{
return data;
}
Node* Next()
{
return next;
}
};
class List
{
Node *head;
public:
List() { head = NULL; };
void Insert(int d)
{
int value;
value = d;
Node* n1 = new Node(value);
n1->SetNext(NULL);
Node *temp = head;
if(temp != NULL)
{
while(temp->Next() != NULL)
{
temp = temp->Next();
}
temp->SetNext(n1);
}
else
head = n1;
};
void Delete()
{
int value;
cout<<"enter a value to Delete"<<endl;
cin>>value;
Node* temp;
temp = head;
Node *prev;
if(temp == NULL)
{
cout<<"List is empty, deletion is not possible"<<endl;
}
else
{
if(temp->Next() == NULL)
{
if(temp->Data() == value)
{
delete temp;
head = NULL;
}
else
{
cout<<"Entered Data value is not available in the List"<<endl;
}
}
else if((temp->Data() == value))
{
head = temp->Next();
delete temp;
}
else
{
while(temp->Next() != NULL)
{
prev = temp;
temp = temp->Next();
if((temp->Data() == value) && (temp->Next() != NULL))
{
prev->SetNext(temp->Next());
delete temp;
}
else if(temp->Data() == value && temp->Next() == NULL)
{
prev->SetNext(NULL);
delete temp;
}
}
}
}
};
void Print()
{
Node *temp = head;
if ( temp == NULL )
{
cout << "EMPTY" << endl;
return;
}
if ( temp->Next() == NULL )
{
cout << temp->Data();
cout << " --> ";
cout << "NULL" << endl;
}
else
{
do
{
cout << temp->Data();
cout << " --> ";
temp = temp->Next();
}
while ( temp != NULL );
cout << "NULL" << endl;
}
};
void isEmpty()
{
if(head == NULL)
cout<<"List is Empty"<<endl;
else
cout<<"List is not Empty"<<endl;
};
};
int main()
{
List l1;
char ch;
do
{
cout<<"\n Linked List "<<endl;
cout<<"I. Insert \t D. Delete"<<endl;
cout<<"P. Print \t E. isEmpty \t X.EXIT"<<endl;
cout<<"Enter Your Choice :"<<endl;
cin>>ch;
if((ch>=97)&&(ch<=122))
{
ch=ch-32;
}
switch(ch)
{
case 'I': int value;
cout<<"\n***** Inserting *****"<<endl;
cout<<"enter a value to insert"<<endl;
cin>>value;
l1.Insert(value);
break;
case 'D': cout<<"\n***** Delete *****"<<endl;
l1.Print();
cout<<"\nDelete any value from the above listed"<<endl;
l1.Delete();
system("pause");
break;
case 'P': cout<<"\n***** Print *****"<<endl;
l1.Print();
system("pause");
break;
case 'E': cout<<"\n***** isEmpty *****"<<endl;
l1.isEmpty();
system("pause");
break;
case 'X': exit(1);
break;
default: cout<<"\n Invalid Choice"<<endl;
}
system("cls");
}
while(1);
system("pause");
return 0;
}
Your Delete() function is overly complicated. It can be greatly simplified. For that matter, most of your List code can be simplified. Try something more like this instead:
#include <iostream>
using namespace std;
class Node
{
private:
int data;
Node *next;
public:
Node(int d = 0) : data(d), next(NULL) {}
void SetNext(Node *nextNode)
{
next = nextNode;
}
int Data() const
{
return data;
}
Node* Next() const
{
return next;
}
};
class List
{
private:
Node *head;
Node *tail;
public:
List() : head(NULL), tail(NULL) {}
~List() { Clear(); }
void Clear()
{
Node *temp = head;
Node *next;
head = tail = NULL;
while ( temp != NULL )
{
next = temp->Next();
delete temp;
temp = next;
}
}
void Insert(int d)
{
Node* n1 = new Node(d);
if ( head == NULL )
head = n1;
if ( tail != NULL )
tail->SetNext(n1);
tail = n1;
}
bool Delete(int value)
{
Node* temp = head;
Node *prev = NULL;
while ( temp != NULL )
{
Node* next = temp->Next();
if ( temp->Data() == value )
{
if( prev != NULL )
prev->SetNext(next);
if( head == temp )
head = next;
if( tail == temp )
tail = prev;
delete temp;
return true;
}
prev = temp;
temp = next;
}
return false;
}
void Print() const
{
Node *temp = head;
if ( temp == NULL )
{
cout << "EMPTY" << endl;
}
else
{
do
{
cout << temp->Data() << " --> ";
temp = temp->Next();
}
while ( temp != NULL );
cout << " NULL" << endl;
}
}
bool isEmpty() const
{
return (head == NULL);
}
};
int main()
{
List l1;
char ch;
do
{
cout << "\n Linked List " < <endl;
cout << "I. Insert \t D. Delete \t C. Clear" << endl;
cout << "P. Print \t E. isEmpty \t X. EXIT" << endl;
cout << "Enter Your Choice :" << endl;
cin >> ch;
if ( (ch >= 'a') && (ch <= 'z') )
{
ch -= 32;
}
switch (ch)
{
case 'I':
{
int value;
cout << "\n***** Inserting *****" << endl;
cout << "enter a number to insert" << endl;
if ( cin >> value )
l1.Insert(value);
else
{
cout << "\nYou did not enter a valid number" << endl;
system("pause");
}
break;
}
case 'D':
{
cout << "\n***** Delete *****" << endl;
if ( l1.isEmpty() )
{
cout << "List is empty, deletion is not possible" << endl;
break;
}
l1.Print();
cout << "\nDelete any number from the above list" << endl;
int value;
cout << "enter a number to delete" << endl;
if ( cin >> value )
{
if ( l1.Delete(value) )
cout << "Entered number has been deleted from the List" << endl;
else
cout << "Entered number is not available in the List" << endl;
}
else
cout << "\nYou did not enter a valid number" << endl;
system("pause");
break;
}
case 'C':
{
cout << "\n***** Clear *****" << endl;
l1.Clear();
cout << "List is now empty" << endl;
system("pause");
break;
}
case 'P':
{
cout << "\n***** Print *****" << endl;
l1.Print();
system("pause");
break;
}
case 'E':
{
cout << "\n***** isEmpty *****" << endl;
if ( l1.isEmpty() )
cout << "List is Empty" << endl;
else
cout << "List is not Empty" << endl;
system("pause");
break;
}
case 'X':
exit(1);
break;
default:
cout << "\n Invalid Choice" << endl;
system("pause");
break;
}
system("cls");
}
while (1);
system("pause");
return 0;
}
With that said, you really should be using the std::list class instead, or even the std::forward_list class in C++11 and later. Let the STL manage the nodes for you, eg:
#include <iostream>
#include <list>
#include <algorithm>
using namespace std;
class List
{
private:
list<int> l;
public:
void Clear()
{
l.clear();
}
void Insert(int d)
{
l.push_back(d);
}
bool Delete(int value)
{
list<int>::iterator iter = find(l.begin(), l.end(), value);
if( iter != l.end() )
{
l.erase(iter);
return true;
}
return false;
}
void Print() const
{
if ( l.empty() )
{
cout << "EMPTY" << endl;
}
else
{
list<int>::iterator iter = l.begin();
do
{
cout << *iter << " --> ";
}
while ( ++iter != l.end() );
cout << " NULL" << endl;
}
}
bool isEmpty() const
{
return l.empty();
}
};
I'm making a list in C++ from scratch, not using the STL list funciton. My program is designed for the user to insert a new item (string) to the list, one at a time. The items are supposed to be sorted as they are inserted, and it partially works. The user is supposed to be able to print them forwards and backwards.
Examples:
I insert: 1, 3, 2 - result forward: 1, 2, 3 - backwards: 3, 2, 1
I insert 1, 3, 2, 4 - result forward: 1, 4, 2, 3 - backwards: 3, 2, 4, 1
I insert 4, 2, 3 - result forward: 2, 3, 4 - backwards: 4, 3, 2
I insert 4, 2, 3, 1 - result forward: 1, 4 - backwards: 1, 3 repetedly until program crashes
These are a few examples, I could include more. I can not for the life of me see what's wrong wth my code. I have gotten help from people I know who are great coders, but they were unable to see the problem, after looking at it for a couple hours. I've been stuck at this for days now, and I just don't see it.
Here is my code (comments are in Norwegian, sorry!):
main.cpp
#include <iostream>
#include <cstdlib>
#include <string>
using namespace std;
//definerer noden
struct node
{
string data; //det noden inneholder
node* next; //nestepeker
node* prev; //forrigepeker
};
//definerer funksjonene
bool isEmpty(node* first);
char menu();
void insertAsFirstElement(node* &first, node* &end, string data);
void insert(node* &first, node* &end, string data);
void remove(node* &first, node* &end, string data);
void showList(node* first);
void printBackwards(node* end);
//er noden tom?
bool isEmpty(node* first)
{
if(first == NULL)
return true;
else
return false;
}
//sender valgskjermen til konsollen
char menu()
{
char choice;
cout << "Welcome to LISTOMANIA 3000x! \n" << endl;
cout << "Press <1> to add an item" << endl;
cout << "Press <2> to remove item on top" << endl;
cout << "Press <3> to display the list forward" << endl;
cout << "Press <4> to display the list backwards" << endl;
cout << "Press <5> to exit" << endl;
cout << "\nInput: ";
cin >> choice;
return choice;
}
//hvis lista er tom, sett inn node som første element:
void insertAsFirstElement(node* &first, node* &end, string data)
{
cout << "temp is first\n";
node* temp = new node;
temp->data = data;
temp->next = NULL;
temp->prev = NULL;
first = temp;
end = temp;
}
//hvis lista ikke er tom, sett inn noden sortert:
void insert(node* &first, node* &end, string data)
{
if(isEmpty(first))
{
insertAsFirstElement(first, end, data);
}
else
{
node* temp = new node;
temp->data = data;
node* n = first;
while(n)
{
if(n->data > temp->data)
{
cout << "temp BEFORE n" << endl;
temp->prev = n->prev;
temp->next = n;
n->prev = temp;
if(temp->prev)
{
temp->prev->next = temp;
}
else
{
first = temp;
}
}
else if(n->data <= temp->data)
{
cout << "temp AFTER n" << endl;
//temp = new node;
//temp->data = data;
temp->prev = n;
temp->next = n->next;
n->next = temp;
if(temp->next)
{
temp->next->prev = temp;
}
else
{
end = temp;
}
break;
}
n = n->next;
}
}
}
//sletter valgt node
void remove(node* &first, node* &end, string data)
{
string delItem;
node* temp;
if(isEmpty(first))
cout << "\nNothing to delete, the list is empty!\n------------------------------------------------\n------------------------------------------------\n";
else if(first == end)
{
cout << "\nYou removed <" << first->data << ">!" << endl;
delete first;
first = NULL;
end = NULL;
cout <<"------------------------------------------------\n------------------------------------------------\n";
}
else
{
node* temp = first;
cout << "You removed <" << temp->data << ">!" << endl;
first = first->next;
delete temp;
cout <<"------------------------------------------------\n------------------------------------------------\n";
}
}
//skriver ut listen alfabetisk
void showList(node* first)
{
node * temp = first;
if(isEmpty(first))
{
cout << "\nThe list is empty!\n";
}
else
{
cout << "\nThe list contains: \n\n";
while(temp != NULL)
{
cout << temp->data << endl;
temp = temp->next;
}
}
cout << "------------------------------------------------\n";
cout << "------------------------------------------------\n";
}
//skriver ut listen omvendt alfabetisk
void printBackwards(node* end)
{
node * temp = end;
if(isEmpty(end))
{
cout << "\nThe list is empty!\n";
}
else
{
cout << "\nThe list contains: \n\n";
while(temp != NULL)
{
cout << temp->data << endl;
temp = temp->prev;
}
}
cout << "------------------------------------------------\n";
cout << "------------------------------------------------\n";
}
//mainfunksjon
int main()
{
node* first = NULL;
node* end = NULL;
char choice;
string data;
do
{
choice = menu();
switch(choice)
{
case '1': cout <<"\nPlease add something to the list: ";
cin >> data;
insert(first, end, data);
cout << "------------------------------------------------\n------------------------------------------------\n";
break;
case '2': remove(first, end, data);
break;
case '3': showList(first);
break;
case '4': printBackwards(end);
break;
case '5': cout << "\nSystem exit...\n";
break;
default: cout << "\nInvalid input!\n------------------------------------------------\n------------------------------------------------\n";
}
}while(choice != '5');
return 0;
}
Just ignore the lines of hyphens, they are just there to make the program look prettier when it is run.
Please note that I am a beginner! There might be lots of other mistakes too, other than my problem. Also ignore the remove function, as I haven't gotten to that problem yet...
check two lines that I added with comments //1.this line and //2.this line the fist one is called when temp<n so you have to compare temp with previous node of n, and the second one is for when temp>=n so you have to do is to compare temp with next node of n. with what I said so far it is clear that you have to remove the line that I commented with //4.you should remove this line : n = temp->next; this is what cause your last problem. Also you have another mistake, you have to remove the break; it leaves your listed in the middle of the sort so your sort never completed and that is what cause the other problem.
while(n)
{
if(n->data > temp->data)
{
cout << "temp BEFORE n" << endl;
temp->prev = n->prev;
temp->next = n;
n->prev = temp;
if(temp->prev)
{
temp->prev->next = temp;
}
else
{
first = temp;
}
n = temp->prev; //1.This line
}
else if(n->data <= temp->data)
{
cout << "temp AFTER n" << endl;
//temp = new node;
//temp->data = data;
temp->prev = n;
temp->next = n->next;
n->next = temp;
if(temp->next)
{
temp->next->prev = temp;
}
else
{
end = temp;
}
n = temp->next; //2.This line
//3.you should comment this line : break;
}
//4.you should remove this line : n = temp->next;
}
I got some help from more people, and we found a solution. Here is my insert fucntion:
//hvis lista ikke er tom, sett inn noden sortert:
void insert(node* &first, node* &end, string data)
{
if(isEmpty(first))
{
insertAsFirstElement(first, end, data);
}
else
{
node* temp = new node;
temp->data = data;
temp->next = first;
temp->prev = NULL;
first->prev = temp;
first = temp;
}
//sortering
if(first != NULL)
{
node* current = first;
node* prev = NULL;
node* tempNode = NULL;
while(current->next != NULL)
{
tempNode = current->next;
//cout << "current: " << current->data << " tempNode: " << tempNode->data << endl;
if(current->data > tempNode->data)
{
//cout << "swapped " << "current: " << current->data << " tempNode: " << tempNode->data << endl;
swap(current->data, tempNode->data);
}
else
{
prev = current;
current = current->next;
}
}
}
}
This sorts the data if it is a string, with a little bug on numbers, interpreted as a string, which can be solved with converting all numbers to an int.
EDIT:
That bug with the nubmers isn't really a bug at all. The list thinks 11 is smaller than 5, but that is because every input is interprated as a string. So then if you think that 1 = a and 2 = b, then it makes perfect sense that 11 < 5. So if you want them to be sorted how it would logically be done, having 11 > 5, you'd have to convert all numbers to an int.