Linked list not working for input - c++

I'm writing code that takes integers that are input from the user and creates a linked list and then prints out the list. However, when I enter values 1,2,3,4,5, the output is only 5 5 5 5 5
Please tell me where am i wrong here.
The code is as follows:
include"iostream"
using namespace std;
struct node
{
int number;
node* next;
};
int main()
{
node* head;
head = NULL;
int i,n,x;
cin>>n;
cout<<endl;
for(i=0;i<n;i++)
{
cin>>x;
//Insert(x);
node* temp;
temp = new node;
temp->number = x;
temp->next = NULL;
head = temp;
}
//Print();
node* temp;
temp = head;
while(temp != NULL)
{
for(int j=0; j<n; j++)
cout<<temp->number<<" ";
temp = temp->next;
}
}

Remember that when setting the head pointer, you should only do so when the list is empty (i.e when head == NULL). We should do this after we create the new node so we know what to set head to:
node* temp = new node;
temp->number = x;
temp->next = NULL;
if (head == NULL) // if the list is empty then...
head = temp; // temp is the start of the list
There's also another problem. temp is supposed to be added to the end of the list each time it's created. If the list is empty then head is the end of the list, but if the list already has elements then we need to go to the end and set the next pointer of that node to temp. This is fairly straightforward, all it takes is a while loop to iterate over the list to the end:
if (head == NULL)
head = temp;
else // the list is not empty
{
// so we need to go to the end
node* p = head;
while (p->next != NULL)
p = p->next; // keep going through
// p now points to the last node
p->next = temp;
}
There's also the option of keeping a prev node that points to the last element inserted. This makes it so that we don't have to go through the list each time to find the end:
node* head = NULL, prev = NULL;
for (/* ... */)
{
// ...
if (head == NULL)
head = prev = temp;
else
{
prev->next = temp;
prev = temp;
}
}
The last thing is the way you're printing. You shouldn't have a nested for loop here:
while (temp != NULL)
{
for(int j = 0; j < n; j++)
cout << temp->number << " ";
temp = temp->next;
}
Taking it out will make it print correctly.

This looks a bit wrong:
while(temp != NULL)
{
for(int j=0; j<n; j++)
cout<<temp->number<<" "; // Only this is part of the for() loop
temp = temp->next; // This happens after the for() loop ends
}
Only the first line gets executed by the for() loop so it keeps outputting the same number. Why is the for loop there anyway? What is it supposed to do?
Try this:
while(temp != NULL)
{
cout<<temp->number<<" ";
temp = temp->next;
}
See if that works better.
ALSO:
As #crashmstr pointed out your insert logic is wrong:
for(i=0;i<n;i++)
{
cin>>x;
//Insert(x);
node* temp;
temp = new node;
temp->number = x;
temp->next = NULL; // this should point to the nextnode
head = temp;
}
Try:
for(i=0;i<n;i++)
{
cin>>x;
//Insert(x);
node* temp;
temp = new node;
temp->number = x;
temp->next = head; // the current begining
head = temp;
}
*ALSO 2:
include"iostream" // not right
Please use:
#include <iostream> // correct!

Related

singly linked list insertion issue

I was trying to insert element at end of a linked list, but if I comment the break in my while loop, it goes to a continuous loop, I'm unable to figure out why
code:
head=NULL;
node *temp=head;
for(int i=0;i<5;i++)
{
//temp=head;
node* t1=new node;
if(head==NULL)
{
t1->a=i;
t1->next=NULL;
head=t1;
}
else
{
temp=head;
while(temp!=NULL)
{
if(temp->next==NULL)
{
t1->a=i;
t1->next=NULL;
temp->next=t1;
//break;
}
temp=temp->next;
}
}
}
temp=head;
while(temp!=NULL)
{
cout<<temp->a<<endl;
temp=temp->next;
}
Your while loop is trying to traverse the new node you have just added again and again. Breaking the loop after the insert operation is correct here, otherwise the while loop may loop indefinitely.
Your while loop runs forever without the break because temp is never set to NULL to stop the loop. When the while loop reaches the last node in the list, it appends the new node to the end, then sets temp to that node. So the next loop iteration sees that node, appends again, and again, and again, endlessly.
So, you need to break the while loop when the last node has been reached:
for(int i = 0; i < 5; i++)
{
node* t1 = new node;
t1->a = i;
t1->next = NULL;
if (head == NULL)
{
head = t1;
}
else
{
node *temp = head;
while (temp != NULL)
{
if (temp->next == NULL)
{
temp->next = t1;
break;
}
temp = temp->next;
}
}
}
In which case, the while loop can be simplified to not need break at all:
for(int i = 0; i < 5; i++)
{
node* t1 = new node;
t1->a = i;
t1->next = NULL;
if (head == NULL)
{
head = t1;
}
else
{
node *temp = head;
while (temp->next != NULL)
{
temp = temp->next;
}
temp->next = t1;
}
}
That being said, this whole code can be greatly simplified further, to not reiterate the entire list on each iteration of the outer for loop, and to not use an if.. else to decide whether or not to set the head:
node **temp = &head;
while (*temp != NULL)
{
temp = &((*temp)->next);
}
for(int i = 0; i < 5; i++)
{
node* t1 = new node;
t1->a = i;
t1->next = NULL;
*temp = t1;
temp = &(t1->next);
}

Insertion in Singly Linked List running on infinite loop

Linked List PrintNode function is running on an infinite loop.
class Node{
public:
int data;
Node* next;
};
Node * head; //first variable of inked list
void Insert(int x){
//insertion at beginning
Node* p = new Node;
p->data = x;
p->next = NULL; //when list is empty
//two scenarios to insert node
//one when linked list is empty
if (head == NULL){
head = p; //head becomes the first node
}
//if linked list is not empty
if (head != NULL){
p->next = head;
head = p; //pointing head at the newly created node
}
}
void PrintNode(Node* head){
for ( Node * temp = head; temp != nullptr; temp = temp->next )
{
cout << temp->data << "->";
}
}
int main (){
head = NULL; //points nowhere
int n;int x;
cin >> n;
for(int i = 0 ; i < n ;i ++){
cout << "Enter element" << endl;
cin >> x;
Insert(x);
}
PrintNode(head);
}
I expect the output to be list printed as for example: 1->2->3-> but,
running on an infinite loop.
The first Node you add ends up pointing at itself. Take a look at this chunk of code from Insert
if (head == NULL){
head = p; //head becomes the first node
}
//if linked list is not empty
if (head != NULL){
p->next = head;
head = p; //pointing head at the newly created node
}
You'll point head at your new Node, then enter the next if since head isn't NULL. If you replace the second if with an else, you should be fine.
Look carefully at this code:
if (head == NULL){
head = p; //head becomes the first node
}
//if linked list is not empty
if (head != NULL){
p->next = head;
head = p; //pointing head at the newly created node
}
When head is NULL both branches of code get run resulting in your head node pointing to itself. The correct code would be:
if (head == nullptr){
head = p; //head becomes the first node
}
//if linked list is not empty
else{
p->next = head;
head = p; //pointing head at the newly created node
}
When you update the head pointer as you insert your first element, both if statements will be executed and the head pointer will never be empty in the second if statement, so it should be if then else, like below
if (head == NULL){
head = p; //head becomes the first node
}
//if linked list is not empty
else if (head != NULL){
p->next = head;
head = p; //pointing head at the newly created node
}

Adding Data to Linked List after Sorting

I am trying to read a text file,sort it each user with respect to their number in text file then add it to the linked list.then display it again respect to user number of each node in descending order.also i am trying to add functions to edit like deleting or updating the content.
txt file is like
John Doe ; 10
Sally Tully ; 5
James Watson ; 12
what i have achieved is this:
list.h:
#include<string>
#ifndef LIST_H
#define LIST_H
class list{
private:
struct node{
std::string data;
node* next;
};
typedef struct node* nodePtr;
nodePtr head;
nodePtr curr;
nodePtr temp;
public:
list();
void AddNode(std::string addData);
void DeleteNode(std::string delData);
void PrintList();
};
#endif
list.cpp
#include <cstdlib>
#include <iostream>
#include "list.h"
using namespace std;
list::list(){ //constructor
head = NULL;
curr= NULL;
temp=NULL;
}
void list::AddNode(string addData){
nodePtr n = new node; //nodePtr is node*
n->next=NULL; //find node n is pointing to, access its next element make it point to null
n->data= addData;
if(head != NULL) { // if we have at least 1 element in the list .
curr = head; // take the current pointer we are working with and make it same with head pointer pointing to.(current= front of list)
while(curr->next !=NULL){ // are we at the end of the list.
curr = curr->next;//we are not end of the list.curr pointer points next node.
}
curr->next = n;
}else{ //if we dont have at least 1 element in the list.
head =n;
}
}
void list::DeleteNode(string delData){
nodePtr delPtr = NULL;
temp = head;
curr = head;
while(curr != NULL && curr->data != delData){ // look for data user wants to delete
temp = curr;
curr = curr->next;
}
if(curr == NULL){ // we cant find we are looking for.
cout << delData << "not in list"<<endl;
delete delPtr;
}else{ // we found it
delPtr = curr;
curr = curr->next; // with those 2 lines we are patching the hole in the list.
temp->next = curr;
if(delPtr == head){
head = head->next;
temp = NULL;
}
delete delPtr;
cout<<delData<<"deleted"<<endl;
}
}
void list::PrintList(){
curr = head;
while(curr !=NULL){
cout<<curr->data<<endl;
curr = curr->next;
}
}
int main(){
list mylist;
mylist.AddNode("hello");
mylist.AddNode("how u doin");
mylist.AddNode("good");
mylist.PrintList();
return 0;
}
after reading the txt file should i put them into a vector(or directly to list) then sort then put to linked list ? i guess its wrong i should put them directly then sort before printing on screen. also i dont have any idea how to do updating node by user input function.
update:
I achieved adding content to linked list from txt file.
string file;
ifstream filein;
cout << "Enter file name:"<<endl;
cin >> file;
filein.open(file);
for(;filein.fail();)
{
cout << "Cannot open the file"<<endl;
cout << "Enter file name:"<<endl;
cin >> file;
filein.open(file);
}
string cline;
string cname;
string csurname;
int money;
string smoney;
string lastdata;
char delimiter=';';
while (std::getline(filein, cline)){
std::istringstream iss(cline);
while(iss >> cname >> csurname >> delimiter >> money){
ostringstream temp; // int to string
temp<<money;
smoney=temp.str();
lastdata = cname+" "+csurname+" "+smoney;
mylist.AddNode(lastdata);
}
}
mylist.PrintList();
now it adds like
john doe 10
sally tully 5
the problem is how im gonna reach this 10 and sort them while printing on screen
One way o solve the problem is to create two kinds of methods, one that deals with the comparison and other one that sort the linked list.
The below method deals with comparison. In this case it is comparing the length of the string, but it could be anything.
bool list::IsGreater(nodePtr a, nodePtr b)
{
if (a->data.length() > b->data.length())
return true;
return false;
}
The second method sorts the linked list. Even if there is a sort method, the easiest way is to keep the list sorted during the method AddNode.
void list::SortList() {
for (nodePtr i = head; i != NULL; i = i->next) {
nodePtr prev = NULL;
for (nodePtr j = head; j != NULL && j->next != NULL; j = j->next) {
if (IsGreater(j, j->next)) {
if (prev)
prev->next = j->next;
else
head = j->next;
nodePtr tmp = j->next;
j->next = j->next->next;
tmp->next = j;
j = tmp;
}
if (prev == NULL)
prev = head;
else
prev = j;
}
prev = i;
}
}

Printing the singly linked list

I am a newbie to programming
Here I wrote a code for accepting and displaying the values using linked list.
However the code takes all the values but displays only the last value
Here is the code
#include <iostream>
using namespace std;
struct node {
int value;
node* next;
};
class llist {
public:
void create();
void display();
node* head = NULL;
};
void llist::create()
{
struct node* temp;
temp = NULL;
struct node* p;
p = new struct node;
cin >> p->value;
if (head == NULL) {
head = p;
}
else {
temp = head;
while (temp->next != NULL) {
temp = temp->next;
}
temp->value = p->value;
temp->next = NULL;
}
}
void llist::display()
{
struct node* temp = head;
while (temp != NULL) {
cout << "VALUE:" << temp->value << endl;
temp = temp->next;
}
}
int main()
{
int n, i;
llist l1;
cin >> n;
for (i = 0; i < n; i++)
l1.create();
cout << "Displaying list\n";
l1.display();
return 0;
}
Input:
4
1
2
3
4
Displaying list
VALUE:4
I am wondering what went wrong...
Change this:
else {
temp = head;
while (temp->next != NULL) {
temp = temp->next;
}
temp->value = p->value;
temp->next = NULL;
}
to this:
else {
temp = head;
while (temp->next != NULL) {
temp = temp->next;
}
temp->next = p;
}
When inserting a new element at the end of a linked list, you find the last element inside the while loop and put it in the temp variable. Then you assign its next value to your new p element. The way you were doing before, you were just overriding the integer number of the last element. That is why when you printed your list you only got the last number you entered.
Also, when creating a new element p, be sure to initialize its next value to NULL:
p = new struct node;
p->next = NULL;
Problem is with the last 2 lines in the else block.
You are overwriting the value and maintaining just the single mode in your list class. And that's the reason, only last value is displayed.
Replace
temp->value = p->value;
temp->next = NULL;
With
temp->next = p;

Inserting an integer at the end of the list and deleting at nth position

So, in my linked list program, what I want it to do is to ask the user how many numbers to input, and enter the numbers, and add those numbers at the end of the list. Then, it will print the list. After that, the user will choose a position of element in the list to delete and the list will be printed again.
#include <iostream>
using namespace std;
struct Node{
int data;
Node* link;
};
Node* head;
void Insert(int data){ //insert an integer at the end of the list
Node* temp = new Node();
Node* temp2 = new Node();
temp->data = data;
temp->link = NULL;
if(head = NULL){
head = temp;
return;
}
temp2 = head;
while(temp2->link != NULL){
temp2 = temp2->link;
}
temp2->link = temp;
}
void Delete(int n){ //delete an integer at nth position
Node* temp1 = new Node();
temp1 = head;
if(n == 1){ //if the first node is to be deleted
head = temp1->link; //now head points to second node
delete temp1; //delete first node
return;
}
for(int i = 0; i < n-2; i++){
temp1 = temp1->link; //temp1 points to (n-1)th node
}
Node* temp2 = temp1->link; //temp2 points to nth node
temp1->link = temp2->link; // pointing to (n+1)th node
delete temp2; //deleting nth node
}
void Print(){ //print out the list
Node* printNode = head;
cout << "List: ";
while(printNode != NULL){
cout << printNode->data;
cout << " ";
printNode = printNode->link;
}
cout << "\n";
}
int main(){
int x, count, n;
head = NULL; //start with an empty list
cout << "How many numbers? " << endl;
cin >> count;
for(int i = 0; i < count; i++){
cout << "Enter number: ";
cin >> x;
Insert(x);
}
Print();
cout << "Enter position to delete: ";
cin >> n;
Delete(n);
Print();
return 0;
}
After accepting the first number, the program stops working. Can I know where I did the code wrong and what can I do to make this code more efficient? Thanks in advance.
Big facepalm on my part, only a small mistake. Code has been corrected.
if(head == NULL){
head = temp;
return;
}
You might need to rethink your insertion function. The part that your code crashes on is during the while loop insertion. If you want temp2 to hold data then you need to dynamically allocate space for it which you did. However, you are just using it as a position indicator (to traverse the list) - so why do you need to allocate space just to point to head or any other nodes location in your list?
Here's how I would insert into the list (at the back of course):
void Insert(int data){ //insert an integer at the end of the list
Node* temp = new Node();
// This is to ensure that temp was created -> Also called defensive programming.
if (!temp)
{
cout << "We did not have enough space alloted to dynamically allocate a node!" << endl;
exit(1);
}
temp->data = data; // Bad nominclature for program; Don't use the same name twice.
temp->link = NULL;
if (head == NULL)
{
head = temp;
}
else
{
// This is to help traverse the linked list without having to
// manipulate the position of what head points to.
Node *Pos_Indicator = head;
while (Pos_Indicator->link != NULL)
{
Pos_Indicator = Pos_Indicator->link;
}
// We are at the end of the list, it is now safe to add.
Pos_Indicator->link = temp;
// Should probably have a check here for whether it was successful or not.
}
}
I was able to compile and run your code to completion with no other problems. Let me know if this helps!
EDIT: or you know (head = NULL) to (head == NULL) works too :(