So I'm working on a linked list code and I have two functions: one to build the list forward and one to build the list backward.
My code runs but the problem I am having is that it is only printing out the function to buildlistForward() but not buildlistBackward()
#include <iostream>
#include <fstream>
using namespace std;
ifstream fin;
//ofstream fout;
struct nodeType
{
int num;
nodeType *next;
};
void buildlistForward();
void buildlistBackward();
//void deleteHead(nodeType);
int main()
{
fin.open("testscores_input.txt");
buildlistForward();
buildlistBackward();
return 0;
}
void buildlistForward()
{
nodeType *head = NULL, *trail = NULL, *current = NULL;
int digit;
cout << "The list built forward is: " << endl;
while (fin >> digit)
{
if (head == NULL)
{
head = new nodeType;
head->num = digit;
head->next = NULL;
trail = head;
}
else
{
current = new nodeType;
current->num = digit;
current->next = NULL;
trail->next = current;
trail = current;
}
}
current = head;
while (current != NULL)
{
cout << current->num << endl;
current = current->next;
}
}
void buildlistBackward()
{
nodeType *head1 = NULL, *current1;
int digit;
cout << "The list built backward is: " << endl;
while (fin >> digit)
{
if (head1 == NULL)
{
head1 = new nodeType;
head1->num = digit;
head1->next = NULL;
}
else
{
current1 = new nodeType;
current1->num = digit;
current1->next = NULL;
current1->next = head1;
head1 = current1;
}
}
current1 = head1;
while (current1 != NULL)
{
cout << current1->num << endl;
current1 = current1->next;
}
}
The program does buildlistForward() first so when the end of the file is read there is nothing to read into for buildlistBackward() you would need to read from the file again by opening the ifstream, however you could also just print the linked list backwards by implementing a tail, and accessing the last node and print each from last to first, rather than reading the input and printing as each node is inputted.
Related
I don't know where I'm going wrong. Output shows 1 upon inputting 1 2 3 -1 (-1 to terminate insertion of nodes). Help is appreciated!
I can't seem to find the error in my code that is resulting in wrong output upon different test cases.
Other approaches to the same problem are also welcome.
Any tips so that i won't commit such errors in the future, along with some fundamentals(generally tips) of linked lists
#include <iostream>
using namespace std;
class Node
{
public:
int data;
Node *next;
Node(int data)
{
this->data = data;
next = NULL;
}
};
Node *insert()
{
int data;
cin >> data;
Node *head = NULL;
Node *tail = NULL;
while (data != -1)
{
Node *n = new Node(data);
if (head == NULL)
{
head = n;
tail = n;
}
else
{
tail->next = n;
tail = tail->next;
}
cin >> data;
}
return head;
}
void print(Node *head)
{
Node *temp = head;
while (temp != NULL)
{
cout << temp->data << " ";
temp = temp->next;
}
}
Node *rev_LL(Node *head)
{
if (head == NULL || head->next == NULL)
{
return head;
}
Node *smallAns = rev_LL(head->next);
Node *temp = smallAns;
while (temp->next != NULL)
{
temp = temp->next;
}
temp->next = head;
head->next = NULL;
return smallAns;
}
int main()
{
Node *head = insert();
print(head);
cout << endl;
cout << "After reversing the Linked list : " << endl;
rev_LL(head);
print(head);
cout << endl;
return 0;
}
You have to assign the return value of rev_LL to head instead of just ignoring that.
int main()
{
Node *head = insert();
print(head);
cout << endl;
cout << "After reversing the Linked list : " << endl;
//rev_LL(head);
head = rev_LL(head); // assign the result
print(head);
cout << endl;
return 0;
}
We are suppose to enter a string, and then find where the string is in the linked list and remove that node
when i insert to the front of the list, so i enter data values a, b, c , d, when i print it it comes up as d,c,b,a. Now i insert to the rear of it, entering f and g, and the list now looks, d,c,b,a,f,g. I want to remove f but it just use the remove function it does not and still output the same list
using namespace std;
struct node {
string data;
node* next;
};
node* addFront(node* s);
node* addRear(node* s);
void remove(node* head, string abc);
void print(node* head);
int main() {
node* head = NULL;
cout << "Enter 5 data strings\n";
cout << "This will be inserted from the back\n";
for (int i = 0; i < 5; i++) {
head = addFront(head);
}
print(head);
cout << "Enter 3 strings and this will be inserted from the back of the orignal string\n";
for (int i = 0; i < 3; i++) {
head = addRear(head);
}
print(head);
cout << "Removing the head node\n";
string n;
cout << "Enter a string to remove\n";
cin >> n;
remove(head, n);
print(head);
}
node* addFront(node* s)
{
node* person = new node;
cin >> person->data;
person->next = s;
s = person;
return s;
}
node *addRear(node*s ) {
node* person = new node;
cin >> person->data;
person->next = NULL;
if (s == NULL) {
return person;
}
else {
node* last = s;
while (last->next != NULL) {
last = last->next;
}
last->next = person;
}
return s;
}
void remove(node* head, string a) {
node* previous = NULL;
node* current = head;
if (current == NULL) {
cout << "Value cannot be found\n";
return;
}
else {
while (previous != NULL) {
if (current->data == a) {
previous->next = current->next;
delete current;
break;
}
current = current->next;
}
}
}
void print(node * head)
{
node* temp = head;
while (temp != NULL) // don't access ->next
{
cout << temp->data << " ";
temp = temp->next;
}
cout << endl;
}
In remove function, previous is most certainly NULL when you hit that while loop.
Perhaps consider a do-while loop instead (with better handling of previous).
You may be better off handling the first node in a different manner since the holder of its previous is essentially the root pointer.
I have got a problem in the sorting method of my linked list. I need to sort nodes in a doubly linked list by transferring links of nodes (entries of nodes). The method is stopped due to nullptr in the last node.
I do not know how to solve this problem. I tried a lot of variants, but no one was successful.
#include "DlinkedList.h"
// Node constructor
Node::Node()
{
this->rhetorician = NULL;
this->prev = NULL;
this->next = NULL;
}
// Node destructor
Node::~Node()
{
}
// List constructor
DlinkedList::DlinkedList()
{
this->length = 0;
this->head = NULL;
}
// Method for adding node at the end
void DlinkedList::appendNode(Rhetorician* rhetorician)
{
if (this->head == NULL) {
Node *new_node = new Node();
new_node->rhetorician = rhetorician;
this->head = new_node;
}
else {
Node *last_node = NULL;
for (Node *node_ptr = this->head; node_ptr != NULL; node_ptr = node_ptr->next)
{
last_node = node_ptr;
}
Node *new_node = new Node();
new_node->rhetorician = rhetorician;
last_node->next = new_node;
new_node->prev = last_node;
}
this->length++;
}
// Method for printing nodes
void DlinkedList::printNodes()
{
for (Node *node_cur = this->head; node_cur != NULL; node_cur = node_cur->next)
{
node_cur->rhetorician->printer();
cout << "---------------------------------------------------------------------------------------------------" << endl;
}
cout << endl << "##################################################################################################\n" << endl;
}
// Method for getting length
int DlinkedList::getLenght()
{
return this->length;
}
// Method for deleting node
void DlinkedList::remove(string name)
{
Node* logout_node = NULL;
for (Node* node_cur = this->head; node_cur != NULL; node_cur = node_cur->next)
{
if (node_cur->rhetorician->name == name)
{
logout_node = node_cur;
}
}
if (this->head != NULL || logout_node != NULL)
{
if (this->head == logout_node)
{
this->head = logout_node->next;
}
if (logout_node->next != NULL)
{
logout_node->next->prev = logout_node->prev;
}
if (logout_node->prev != NULL)
{
logout_node->prev->next = logout_node->next;
}
delete logout_node->rhetorician;
delete logout_node;
this->length--;
}
}
// Method for finding node
void DlinkedList::find(string name)
{
bool ver = false;
Node *n = NULL;
for (Node* node_cur = this->head; node_cur != NULL; node_cur = node_cur->next)
{
if (node_cur->rhetorician->name == name)
{
ver = true;
n = node_cur;
}
}
if (ver)
{
n->rhetorician->printer();
}
else
{
cout << "Rhetorician was not found!";
}
}
// Method for sorting nodes
void DlinkedList::sort()
{
int count = this->getLenght();
Node *tmp, *current;
int i, j;
for (i = 1; i < count; i++)
{
current = this->head;
for (j = 0; j <= count - i - 1; j++)
{
Node *before, *after;
if (current->rhetorician->coefficient > current->next->rhetorician->coefficient)
{
before = current->prev;
after = current->next;
if (before != NULL) {
before->next = after;
}
current->next = after->next;
current->prev = after;
after->next = current;
after->prev = before;
}
tmp = current;
current = current->next;
}
}
}
// List destructor
DlinkedList::~DlinkedList()
{
Node *next_node = NULL;
for (Node *node_cur = this->head; node_cur != NULL; node_cur = next_node)
{
next_node = node_cur->next;
delete node_cur->rhetorician;
delete node_cur;
}
this->head = NULL;
this->length = 0;
}
Main:
#include <iostream>
#include "DlinkedList.h"
#include <fstream>
#include <vector>
#include <sstream>
// Namespace
using namespace std;
// Parser of line to vector array
vector<string> split(string strToSplit, char delimeter)
{
stringstream ss(strToSplit);
string item;
vector<string> splittedStrings;
while (getline(ss, item, delimeter))
{
splittedStrings.push_back(item);
}
return splittedStrings;
}
// File loader
void read_file(const char *name, DlinkedList *list)
{
// Variable for loading line
string line;
{
// Create relation
ifstream file(name);
// Check if file exists
if (file)
{
// Check if file is empty
if (!(file.peek() == ifstream::traits_type::eof()))
{
// Read data from file and put into LinkedList
while (getline(file, line)) {
list->appendNode(new Rhetorician(split(line, ';')[0], split(line, ';')[1],
split(line, ';')[2], stoi(split(line, ';')[3])));
}
}
// Close file
file.close();
}
}
}
// Main method
int main()
{
// Create instance of doubly linked list
DlinkedList *list = new DlinkedList();
// Read file and push data into list
read_file("seznam_enumat.txt", list);
// Print all loaded rhetoricians behind added own one
cout << "\nAll rhetoricians from file:" << endl;
cout << "##################################################################################################\n" << endl;
list->printNodes();
// Append other rhetoricians
list->appendNode(new Rhetorician("Cain", "Foster", "Structural and molecular virology", 7));
list->appendNode(new Rhetorician("Stacy", "Algar", "Dept of microbiology and immunology", 5));
list->appendNode(new Rhetorician("Oded", "Philander", "Experimental plasma physics", 3));
list->appendNode(new Rhetorician("Shay", "Rimon", "Experimental plasma physics", 10));
// Sort rhetoricians in list
list->sort();
// Delete rhetorician by name
//list->remove("Stacy");
// Finder of rhetorician
cout << "\nFound rhetorician:" << endl;
cout << "##################################################################################################\n" << endl;
list->find("Shay");
// Print all sorted rhetoricians
cout << "\nAll rhetoricians:" << endl;
cout << "##################################################################################################\n" << endl;
list->printNodes();
// Destruct list
delete list;
// Check if user click any key
getchar();
return 0;
}
Rhetorician:
#include "Rhetorician.h"
Rhetorician::Rhetorician(string name, string surname, string contribution, int coefficient)
{
this->name = name;
this->surname = surname;
this->contribution = contribution;
this->coefficient = coefficient;
}
void Rhetorician::printer()
{
// Name
cout << "Name:" << endl;
cout << this->name << endl;
// Surname
cout << "Surname:" << endl;
cout << this->surname << endl;
// Contribution
cout << "Contribution:" << endl;
cout << this->contribution << endl;
// Coefficient
cout << "Coefficient:" << endl;
cout << this->coefficient << endl;
}
The main issue is in sort(). It is not handling the pointers correctly.
Take a short example, 3 -> 2 -> 1 and you will get it.
Here is the corrected code with unnecessary variables removed:
void DlinkedList::sort() {
int count = this->getLenght();
Node *current;
int i, j;
for (i = 1; i < count; i++) {
current = this->head;
for (j = 0; j <= count - i - 1; j++) {
Node *before, *after;
if (current->rhetorician->coefficient > current->next->rhetorician->coefficient) {
before = current->prev;
after = current->next;
if (before != nullptr) {
before->next = after;
} else {
// if before = null, it is the head node
this->head = after; // In case before pointer is null, after pointer should be the new head
}
current->next = after->next;
current->prev = after;
if (after->next != nullptr) {
after->next->prev = current; // prev pointer of after->next should be set to current.
}
after->next = current;
after->prev = before;
} else {
current = current->next; // Go to next node only if current->rhetorician->coefficient > current->next->rhetorician->coefficient condition is false.
}
}
}
}
The upwardly sorted list is working super but when I tried to sort the list downwardly only change the character > for < it is not working. Must be changed before node and after node?
// Zero or one element, no sort required.
if (this->head == NULL) return;
if (this->head->next == NULL) return;
// Force initial entry.
int swapped = 1;
while (swapped) {
// Flag as last time, then do one pass.
swapped = 0;
this->current = this->head;
while (this->current->next != NULL) {
Node *before, *after;
if (current->rhetorician->coefficient > current->next->rhetorician->coefficient) {
swapped = 1;
before = current->prev;
after = current->next;
if (before != NULL) {
before->next = after;
}
else {
// if before = null, it is the head node
this->head = after; // In case before pointer is null, after pointer should be the new head
}
current->next = after->next;
current->prev = after;
if (after->next != NULL) {
after->next->prev = current; // prev pointer of after->next should be set to current.
}
after->next = current;
after->prev = before;
}
current = current->next;
}
}// Zero or one element, no sort required.
if (this->head == NULL) return;
if (this->head->next == NULL) return;
// Force initial entry.
int swapped = 1;
while (swapped) {
// Flag as last time, then do one pass.
swapped = 0;
this->current = this->head;
while (this->current->next != NULL) {
Node *before, *after;
if (current->rhetorician->coefficient > current->next->rhetorician->coefficient) {
swapped = 1;
before = current->prev;
after = current->next;
if (before != NULL) {
before->next = after;
}
else {
// if before = null, it is the head node
this->head = after; // In case before pointer is null, after pointer should be the new head
}
current->next = after->next;
current->prev = after;
if (after->next != NULL) {
after->next->prev = current; // prev pointer of after->next should be set to current.
}
after->next = current;
after->prev = before;
}
current = current->next;
}
}
When I call the display function, the first element of linked list is printed twice. I do not know what is wrong with the code. Please help me to figure it out. The code is as follows:
#include <iostream>
using namespace std;
class node{
public:
char data;
node *link;
};
class linklist{
private:
node *start, *temp, *cur;
public:
linklist(){
start = NULL;
}
void insert(char x){
if (start == NULL){
start = new node;
start->data = x;
start->link = NULL;
cur = start;
}
else
while (cur->link != NULL){
cur = cur->link;
}
temp = new node;
temp->data = x;
temp->link = NULL;
cur->link = temp;
}
void display(){
cur = start;
while (cur->link != NULL){
cout << "Value is: " << cur->data << endl;
cur = cur->link;
}
cout << "Value is: " << cur->data << endl;
}
};
int main(){
linklist obj;
obj.insert('e');
obj.insert('t');
obj.insert('r');
obj.insert('w');
obj.insert('l');
obj.display();
system("Pause");
}
the expected output is: etrwl.
Actual output: eetrwl
You have two problems with your code. The first is the missing {...} surrounding your else statement in insert(). In order to have the needed code only apply to the else case, you need to surround the entire else case with braces, e.g.:
else {
while (cur->link != NULL) {
cur = cur->link;
}
temp = new node;
temp->data = x;
temp->link = NULL;
cur->link = temp;
}
}
Secondly, your conditional used for display() is incorrect. You only want to output the contents when cur != NULL not when cur->next != NULL (that is why you tried to tack an extra output statement following the end of the loop to catch your last value). Don't do that, if you find yourself trying to do something like that -- your are probably doing it wrong.
With that change, you simply have:
void display() {
cur = start;
while (cur != NULL) {
cout << "Value is: " << cur->data << endl;
cur = cur->link;
}
}
Putting it altogether, you have:
#include <iostream>
using namespace std;
class node{
public:
char data;
node *link;
};
class linklist{
private:
node *start, *temp, *cur;
public:
linklist() {
start = NULL;
}
void insert (char x) {
if (start == NULL) {
start = new node;
start->data = x;
start->link = NULL;
cur = start;
}
else {
while (cur->link != NULL) {
cur = cur->link;
}
temp = new node;
temp->data = x;
temp->link = NULL;
cur->link = temp;
}
}
void display() {
cur = start;
while (cur != NULL) {
cout << "Value is: " << cur->data << endl;
cur = cur->link;
}
}
};
int main (void) {
linklist obj;
obj.insert('e');
obj.insert('t');
obj.insert('r');
obj.insert('w');
obj.insert('l');
obj.display();
system("Pause");
}
Example Use/Output
$ ./bin/llinsert
Value is: e
Value is: t
Value is: r
Value is: w
Value is: l
Look things over an let me know if you have further questions.
I am writing a three file C++ program for my class. This program is ordered linked list. The program compiles but crashes when I attempt to insert (Run the program, select choice press enter, type an int to insert and press enter). Any help would be greatly appreciated.
Driver File:
#include "SortedLinkedList.h"
#include <iostream>
using namespace std;
int displayMenu();
void proccessChoice(int, SortedLinkedList&);
int main()
{
SortedLinkedList sSList;
int choice = displayMenu();
do
{
if (choice != 3)
{
proccessChoice(choice, sSList);
}
} while (choice != 3);
return 0;
}
void proccessChoice(int input, SortedLinkedList& l)
{
switch(input)
{
case 1:
int num;
cout << "Please enter a int: ";
cin >> num;
l.addItem(num);
break;
case 2:
l.popFirst();
break;
}
}
int displayMenu()
{
int choice;
cout << "menu" << endl;
cout << "===========" << endl;
cout << "1. add an int" << endl;
cout << "2. Show Sorted Linked List" << endl;
cout << "3. Exit" << endl;
cin >> choice;
cin.ignore();
return choice;
}
Declaration File:
struct sslNode
{
sslNode* next;
int item;
};
class SortedLinkedList
{
private:
sslNode* head;
bool isEmpty ();
public:
SortedLinkedList();
~SortedLinkedList();
void addItem(int);
int popFirst();
};
Implementation File:
#include <iostream>
using namespace std;
#include "SortedLinkedList.h"
SortedLinkedList::SortedLinkedList()
{
head = NULL;
}
SortedLinkedList::~SortedLinkedList()
{
sslNode *temp, *nextLink;
nextLink = head;
while(nextLink != NULL)
{
temp = nextLink->next;
delete nextLink;
nextLink = temp;
}
}
bool SortedLinkedList::isEmpty()
{
return (head == NULL);
}
void SortedLinkedList::addItem(int itemToInsert)
{
sslNode* cur;
sslNode* prev;
sslNode* newNode = new sslNode();
newNode->item = itemToInsert;
newNode->next = NULL;
cur = head;
prev = NULL;
bool moreToSearch (cur != NULL);
while (moreToSearch) //Find insertion point
{
if (cur->item > newNode->item) // while current location has a greater value then what needs to be inserted move pointers forward.
{
prev = cur;
cur = cur->next;
moreToSearch = (cur != NULL);
}
else // if current loacation and what is to be inserted are equal or less then we have found the point of insertion
{
moreToSearch = false;
}
}
if (prev = NULL)
{
newNode->next = head->next;
head = newNode;
}
else
{
prev->next = newNode;
newNode->next = cur;
}
//Insert as only item in list
//Insert in found location
}
int SortedLinkedList::popFirst()
{
sslNode* first;
first = head->next;
head = head->next;
int item = first->item;
return item;
}
Your problem is you forgot an =
if (prev = NULL)
{
newNode->next = head->next;
head = newNode;
}
else
{
prev->next = newNode;
newNode->next = cur;
}
if(prev = NULL)
should be
if(prev == NULL)
right now this is always false because prev becomes null which evaluates to false
and then it fails at
prev->next = newNode;
because your are dereferencing the null pointer.
You'll also want to treat the case where head == NULL before trying to insert anything. Basically if head == NULL, head = newNode;
It crashes because head is initialized to NULL. You probably want to make a dummy head node, depending on your design, or check if its NULL before using it in addItem().
This is how things go down:
SortedLinkedLis
t::SortedLinkedList() // ctor is called
...
head = NULL
SortedLinkedList::addItem(int)
sslNode* cur;
...
cur = head;
...
bool moreToSearch (cur != NULL) // this is surely false
...
if (prev = NULL)
{
newNode->next = head->next;
...//BUT head == NULL ! crash!