I can print one string. But when I try to add two strings it only prints the first string? curr is the beginning of the linked list. If I add one country and tell the program to print it will print the country with the information. However if I add two countries, It will only print the first country.
void LinkedList::printList()
{
curr = head;
while (curr)
{
cout << "Country Name: " << curr->name << ", " << "Gold: " << curr->
gold << ", " << "Silver: " << curr->silver << ", " << "Bronze: " << curr->bronze << "\n";
curr = curr->next;
}
}
bool LinkedList::addCountry(string newName, int gold, int silver, int bronze) {
if (head == NULL)// Adding first element
{
head = new struct Country;
if (head == NULL) return false; // could not create head linked list country
head->name = newName;
head->gold = gold;
head->silver = silver;
head->bronze = bronze;
head->next = NULL;
return true;
} else {
curr = head;
while (curr) {
curr = curr->next;
}
curr = new struct Country;
if (curr == NULL)
return false;
curr->name = newName;
curr->gold = gold;
curr->silver = silver;
curr->bronze = bronze;
curr->next = NULL;
return true;
}
}
#Barmak Shemirani is correct. I think if you had a tail member it would be better:
class LindedList
{
public:
LindedList()
{
tail=head=curr=NULL;
};
Country* head;
Country* curr;
Country* tail;
void printList()
{
curr = head;
while (curr)
{
cout << "Country Name: " << curr->name << ", " << "Gold: " << curr->
gold << ", " << "Silver: " << curr->silver << ", " << "Bronze: " << curr->bronze << "\n";
curr = curr->next;
}
};
bool addCountry(string newName, int gold, int silver, int bronze)
{
curr = new Country;
if (curr == NULL)
return false;
curr->name = newName;
curr->gold = gold;
curr->silver = silver;
curr->bronze = bronze;
curr->next = NULL;
if (head == NULL)
{
head = curr;
tail=curr;
} else
{
tail->next=curr;
tail=curr;
}
return true;
};
};
printList is correct. But in addCountry the last element must point to the new element which was just inserted. For example:
bool LinkedList::addCountry(string newName, int gold, int silver, int bronze)
{
Country *newNode = new Country;
newNode->name = newName;
newNode->gold = gold;
newNode->silver = silver;
newNode->bronze = bronze;
newNode->next = NULL;
if (head == NULL)
{
//adding first element:
head = newNode;
}
else
{
//find the last element currently in the list:
Country *last = head;
while (last->next)//<= ***** edited
last = last->next;
//set newNode as the new last element:
last->next = newNode;
}
return true;
}
Also in C++ you can simple write new Country, it doesn't need struct keyword.
Related
This question already has an answer here:
How to pass head from main to addNode function ? (LinkedList implementation via struct)
(1 answer)
Closed 1 year ago.
My Cpp File code
#include <bits/stdc++.h>
using namespace std;
class Node
{
public:
int data;
Node *next;
};
void insert_at_end(Node *head, int data)
{
Node *temp = new Node();
temp->data = data;
temp->next = NULL;
if (head == NULL)
{
head = temp;
// cout << temp->data << " " << " : " << head->data << endl ;
}
else
{
Node *last = head;
while (last->next != NULL)
{
last = last->next;
}
last->next = temp;
cout << "Inserted " << data << " at the End \n";
}
}
void printList(Node *head)
{
cout << "List : \n";
Node *temp = head;
if (temp == NULL)
cout << "Forgive me !";
while (temp != NULL)
{
cout << "\t" << temp->data << "";
temp = temp->next;
}
}
int main()
{
Node *head = NULL;
insert_at_end(head, 12);
insert_at_end(head, 16);
insert_at_end(head, 71);
insert_at_end(head, 81);
insert_at_end(head, 91);
printList(head);
return 0;
}
It works fine if Head is not NULL ( If already have inserted value at start of list) but as you can see Head is NULL in start it gives a error , Probably the error is in insert_at_end function .
I think i am missing some concept of pointers
the problem with your code is that the function insert_at_end is taking a pointer to the head, meaning it can't modify the head pointer itself.
You could make it this way though :
void insert_at_end(Node **head, int data)
{
Node *temp = new Node();
temp->data = data;
temp->next = NULL;
if (*head == NULL)
{
*head = temp;
}
else
{
Node *last = *head;
while (last->next != NULL)
{
last = last->next;
}
last->next = temp;
cout << "Inserted " << data << " at the End \n";
}
}
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
using namespace std;
struct Node
{
int x;
Node* next = nullptr;
};
typedef Node* nodeptr;
class L
{
private:
nodeptr head = nullptr;
int lengthCount = 0;
public:
void add(const int data);
void print();
void find(const int data);
void pop(const int data);
void listSize();
};
void L:: listSize()
{
cout << "The size of the link list is: " << lengthCount << endl;
}
void L::add(const int data)
{
lengthCount += 1;
Node* newNode = new Node;
newNode->x = data;
if(head == nullptr)
{
head = newNode;
}
else
{
nodeptr temp = head;
while(temp->next != nullptr)
{
temp = temp->next;
}
temp->next = newNode;
}
}
void L::pop(const int data)
{
if(head == nullptr)
{
cout << "Empty List" << endl;
}
else if(head->x == data)
{
head = head->next;
}
else
{
nodeptr temp = head->next;
while(temp != nullptr)
{
if(temp-> x != data)
{
temp = temp->next;
}
else
{
if(temp->next != nullptr)
{
temp = temp->next;
}
else
{
temp->next = nullptr;
}
break;
}
}
}
}
void L::find(const int data)
{
if(head == nullptr)
{
cout << "Empty List" << endl;
}
else
{
nodeptr temp = head;
for(temp; temp != nullptr; temp = temp->next)
{
if(temp->x == data)
{
cout << "Found" << endl;
break;
}
if(temp->next == nullptr)
cout << "Not Found" << endl;
}
}
}
void L::print()
{
nodeptr temp = head;
string line(20,'-');
cout << "Print list" << endl;
cout << line << endl;
while(temp != nullptr)
{
cout << temp->x << endl;
temp = temp->next;
}
cout << line << endl;
}
int main()
{
vector <int> val;
for(int i = 0; i < 10; i++)
val.push_back(5*i);
cout << "Printing list" << endl;
for(auto i : val)
cout << i << " ";
cout << endl;
L listObj;
cout << "Adding list" << endl;
for(auto i : val)
listObj.add(i);
listObj.print();
listObj.listSize();
listObj.find(15);
listObj.print();
cout << "popping 10" << endl;
listObj.pop(10);
listObj.print();
}
The problem that I am having is, I am not able to modify the actually memory of a linked list while using a class.
Im not sure what did I do wrong.
If adding works, i would say the idea of removing a value should work as well.
the remove function is called pop.
the pop function is not removing the value 10, so i am not sure why.
If it is a function that is not in a class, i would say i need to pass a head pointer with & operator then i can actually modify the value.
Please let me know where did I do wrong.
Thanks
Your pop method is not correct, You also have to link the current node with the previous next. It should be like this
void L::pop(const int data)
{
if(head == nullptr)
{
cout << "Empty List" << endl;
}
else if(head->x == data)
{
nodeptr temp = head;
head = head->next;
delete temp;
}
else
{
nodeptr temp = head->next;
nodeptr prev = head;
while(temp != nullptr)
{
if(temp-> x != data)
{
prev = temp;
temp = temp->next;
}
else
{
if(temp->next != nullptr)
{
prev -> next = temp -> next;
delete temp;
}
else
{
delete temp;
prev -> next = nullptr;
}
break;
}
}
}
}
You need to keep track of the "previous" node of the linked list somehow. There's many ways to do it, but the clearest might be:
void L::pop(const int data) {
if(head == nullptr) {
cout << "Empty List" << endl;
return;
}
if(head->x == data) {
node *temp = head;
head = head->next;
delete temp;
return;
}
int *prev = head;
int *temp = head->next;
while (temp != null) {
if (temp->x != data) {
prev = prev->next;
temp = temp->next;
} else {
prev->next = temp->next;
delete temp;
return;
}
}
}
In addition to the answers given already there's a variant without having to track the previous element all the time:
for(Node* tmp = head; tmp->next; tmp = tmp->next;)
{
if(tmp->next->x == data)
{
// OK, one intermediate pointer we need anyway, but we need it
// only once
Node* del = tmp->next;
tmp->next = tmp->next->next;
delete del;
break;
}
}
The for loop as a little bonus is a bit more compact, but that's just a matter of personal taste.
When I call the methods to print the data stored in the nodes of my doubly linked list, nothing prints except for empty strings and 0's
#include <iostream>
#include <string>
using namespace std;
struct node {
int weight;
string name;
node *nextname, *nextweight;
};
node *namehead = NULL, *weighthead = NULL;
bool isEmpty()
{
if (namehead == NULL && weighthead == NULL)
return true;
else
return false;
}
void addperson(int w, string n)
{
node* newNode = new node;
node *prev, *curr = newNode;
if (isEmpty()) {
namehead = newNode;
weighthead = newNode;
}
else {
curr = prev = namehead;
if (curr->name > n) {
namehead = newNode;
newNode->nextname = curr;
}
else {
do {
if (curr->name <= n) {
prev = curr;
curr = curr->nextname;
}
else
break;
} while (curr != NULL);
prev->nextname = newNode;
newNode->nextname = curr;
}
curr = prev = weighthead;
if (curr->weight > w) {
weighthead = newNode;
newNode->nextweight = curr;
}
else {
do {
if (curr->weight <= w) {
prev = curr;
curr = curr->nextweight;
}
else
break;
} while (curr != NULL);
prev->nextweight = newNode;
newNode->nextweight = curr;
}
}
}
void printname()
{
node* curr = namehead;
do {
cout << curr->name << " - " << curr->weight << endl;
curr = curr->nextname;
} while (curr != NULL);
cout << endl;
}
void printweight()
{
node* curr = weighthead;
do {
cout << curr->name << " - " << curr->weight << endl;
curr = curr->nextweight;
} while (curr != NULL);
cout << endl;
}
int main()
{
int w = 0;
string n;
for (int i = 0; i < 15; i++) {
cout << "Enter weight: ";
cin >> w;
if (w == -1)
break;
cout << "Enter name: ";
cin >> n;
addperson(w, n);
}
printname();
printweight();
return 0;
}
Expected output (By name):
John - 220
Steven - 190
Tyler - 150
Expected output (By weight):
Tyler - 150
Steven - 190
John - 220
CURRENT OUTPUT(Both ways):
" " - 0
" " - 0
" " - 0
EDIT
By taking the suggestions in the comments about actually assigning the values w (weight) and n (name) to the temporary node in the add method, the problem has been fixed. Thank you for the help.
curr->weight=w;
curr->name=n;
Assign passed values into weight and name members into placeholder node in the add method:
curr->weight=w;
curr->name=n;
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'm attempting to build a priority queue using a singly linked list. The idea is that I always store the minimum int x inside my Node* head. When the deleteMin() method is called. It should return the minimum value (head->x), and also update the head to the next lowest value in the list.
The problem that I seem to be having is updating the links once a new lowestNode has been found.
SLList.hpp
const int deleteMin() {
int returnVal = this->head->x;
// we need to find the next lowest in the list and update our head, then relink the list.
// first update our head to the next of the current head
this->head = this->head->next;
cout << "head now: " << this->head->x << endl;
// iterate through our nodes searching for a smaller value
Node* currentNode = this->head;
Node* nextNode = NULL;
Node* lowestNode = NULL;
Node* prevNode = NULL;
// Node* prevHead = NULL;
// Node* nextHead = NULL;
while(currentNode != NULL) {
if (currentNode->next->x < this->head->x) {
nextNode = currentNode->next->next;
cout << "nextNode: " << nextNode->x << endl;
lowestNode = currentNode->next;
cout << "lowestNode: " << lowestNode->x << endl;
prevNode = currentNode;
cout << "prevNode: " << prevNode->x << endl;
// prevHead = this->head;
// cout << "prevHead: " << prevHead->x << endl;
// nextHead = this->head->next;
// cout << "nextHead: " << nextHead->x << endl;
// update links
lowestNode->next = this->head->next;
currentNode = this->head;
currentNode->next = nextNode;
this->head = lowestNode;
} else {
currentNode = currentNode->next;
}
}
// decrement the size
this->_size--;
// return the minVal
return returnVal;
}
while(currentNode != NULL && currentNode->next!=NULL) //here you need check for currectNode->next also for NULL condition
{
if (currentNode->next->x < this->head->x) {
nextNode = currentNode->next->next;
cout << "nextNode: " << nextNode->x << endl;
lowestNode = currentNode->next;
cout << "lowestNode: " << lowestNode->x << endl;
//here storing previous node is of no use except for debugging
prevNode = currentNode;
cout << "prevNode: " << prevNode->x << endl;
// update links- here you need to first remove the lowest node from its postion
currentNode->next=nextNode;
//and then add lowest node a the front
lowestNode->next = this->head->next;
this->head = lowestNode;
} else {
currentNode = currentNode->next;
}
}
One problem that I realized was that depending on where the node that contains the lowest int x. If head is directly linked a lower node, then the relinking needed to be a little different than if a lower node was found in the middle of the list.
#ifndef SLLIST_H
#define SLLIST_H
using namespace std;
class SLList
{
struct Node {
int x;
Node *next;
};
private:
int _size;
public:
Node* head; // used to store minimum value of a Node's x
Node* tail;
SLList() :
_size(0),
head(NULL),
tail(NULL) {
}
int size() const {
return this->_size;
}
const int add (const int x) {
// create new node
Node* newNode = new Node();
newNode->x = x;
if (this->_size == 0) {
this->head = newNode;
this->tail = newNode;
} else {
if (newNode->x < this->head->x) {
// update head to new lowest and relink nodes
newNode->next = this->head;
this->head = newNode;
} else {
this->tail->next = newNode;
this->tail = newNode;
}
}
// update list size
this->_size++;
return x;
}
const int deleteMin() {
if (this->_size == 0) return -1;
int returnVal = this->head->x;
cout << "removing min val: " << returnVal << endl;
// we need to find the next lowest in the list and update our head, then relink the list.
// first update our head to the next of the current head
this->head = this->head->next;
// iterate through our nodes searching for a smaller value
Node* currentNode = this->head;
Node* lowestNode = NULL;
for(int i = 0; i < this->_size - 1; i++) {
if (currentNode->next->x < this->head->x) {
lowestNode = currentNode->next;
if (currentNode == this->head) {
cout << "current->next is next to head" << endl;
// only need to update 2 nodes
this->head->next = currentNode->next->next;
lowestNode->next = this->head;
this->head = lowestNode;
currentNode = currentNode->next;
} else {
// update three nodes
cout << "current->next has neighbours" << endl;
// Example scenario
// 3 // nextTo5
// 5 // nextTo4
// 4 // nextTo2
// 2 // nextToNull
// == turns into ==
// 2 // nextTo5
// 5 // nextTo4
// 4 // nextTo3
// 3 // nextToNull
lowestNode->next = this->head->next;
currentNode->next = this->head;
this->head = lowestNode;
currentNode = currentNode->next;
}
} else {
currentNode = currentNode->next;
}
}
// decrement the size
this->_size--;
// return the minVal
return returnVal;
}
const void printList() const {
Node* tmp = this->head;
cout << "printing list... " << endl;
for(int i = 0; i < this->_size; i++) {
cout << tmp->x << endl;
tmp = tmp->next;
}
}
};
#endif // SLLIST_H
Perhaps I should actually use the tail somehow, but currently, I don't really use it for much.