Printing the singly linked list - c++

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;

Related

How to use head while iterating through a linked list?

We are iterating through the linked list with the help of head, that is, we are updating our head as we move forward towards i th position. Please have a look at the fuction insertIthnode. I am inserting my Node at i th position are returning head - and it's still able to print the linked list. I don't know how? head is no longer pointing towards the first node then how is it still able to return a full linked list?
here's the code:
#include <iostream>
using namespace std;
class Node {
public:
int data;
Node *next;
Node(int data) {
this->data = data;
next = NULL;
}
};
int length(Node *head) {
int x = 0;
Node *temp = head;
while (temp != NULL) {
x += 1;
temp = temp->next;
}
return x;
}
void printIthnode(Node *head, int i) {
int n = length(head);
if (i < 0 || i > n - 1) {
cout << -1 << endl;
return;
}
int count = 1;
while (count <= i) {
head = head->next;
count++;
}
if (head) {
cout << head->data << endl;
} else {
cout << "-1" << endl;
}
}
Node *takeinput() {
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 = n;
}
cin >> data;
}
return head;
}
void PrintLL(Node *head) {
Node *temp = head;
while (temp != NULL) {
cout << temp->data << " ";
temp = temp->next;
}
}
Node *insertIthnode(Node *head, int i, int data) {
if (i < 0) {
return head;
} else if (i == 0) {
Node *n = new Node(data);
n->next = head;
head = n;
return head;
}
int count = 1;
while (count <= i - 1 && head != NULL) {
head = head->next;
count++;
if (count == i - 1) {
Node *n = new Node(data);
n->next = head->next;
head->next = n;
return head;
}
return head;
}
}
int main() {
/*Node n1(1);
Node *head=&n1;
Node n2(2);
Node n3(3);
Node n4(4);
Node n5(5);
Node n6(6);
n1.next=&n2;
n2.next=&n3;
n3.next=&n4;
n4.next=&n5;
n5.next=&n6;
*/
Node *head = takeinput();
insertIthnode(head, 3, 7);
PrintLL(head);
}
In the main() function you are creating a head when you are taking input from the user with the help of the "takeInput()" function.
After that, you are calling the function "insertIthnode(head,3,7)" which is returning the head (since the return type is Node) but you are not receiving it in any variable so the head returned from the "insetIthnode" is lost.
Your original head remains the same as per of "takeInput()" function.
If you try to insert ith Node at Index 0 it won't print according to the inserted node.
The problem is that you consider the Node as the linked list. While this is valid, the whole point of the linked list is that you don't lose track of the head. You could use two approaches:
Don't iterate over the head. Instead, use a temporary reference to the head.
Implement a Linked List wrapper. You can keep a constant reference to the head while performing operations over the node.
You pass head by value. Any changes you do to the variable receiving the value of head inside the functions are made to the local variable inside the function only and will not be visible from the call site.
Take your PrintLL function as an example:
void PrintLL(Node *head) { // head is here a local variable
Node *temp = head;
while (temp != NULL) {
cout << temp->data << " ";
temp = temp->next;
}
}
This could be rewritten without the extra variable temp. The name head doesn't make it the same head you used to call the function with:
void PrintLL(Node* head) {
while (head != nullptr) {
cout << head->data << ' ';
head = head->next;
}
}
and it would not affect the head you passed in as a parameter.
Similarly:
void foo(int x) {
++x;
//
}
int main() {
int x = 10;
foo(x);
std::cout << x << '\n'; // prints 10
}

C++ Linked List Not Preserving New Nodes

I'm trying to transition from an almost entirely Java background to getting comfortable with C++. I'm practicing by trying to build a basic Linked List.
#include <iostream>
#include <string>
using namespace std;
struct node
{
string data;
node *next = NULL;
};
class linkedlist
{
public:
node *head;
public:
linkedlist()
{
head = NULL;
}
void addNode(string s)
{
node *newNode = new node;
newNode->data = s;
if(head == NULL)
head = newNode;
else
{
node *temp = head->next;
while(temp != NULL)
temp = temp->next;
temp = newNode;
}
}
void printList()
{
node *temp = head;
while(temp != NULL)
{
cout << temp->data << '\n';
temp = temp->next;
}
}
};
The issue at hand is that once I add a new node using void addNode(string s), it does not appear when I attempt to print the list (starting from the head) with void printList().
For example:
int main(int argc, const char * argv[])
{
int n;
string str;
linkedlist list;
cout << "Please enter the number of strings you'd like to enter:\n";
cin >> n;
for(int i = 0;i < n;i++)
{
string temp;
cout << "Enter string #" << i + 1 << '\n';
cin >> temp;
list.addNode(temp);
}
cout << "This is your linked list: ";
list.printList();
return 0;
}
Using main() above, my results become:
This is your linked list:
(string 1)
I'm pretty certain I'm using pointers improperly here but I don't see why. I've done as much digging as I can on my own for some clarification on how I could be doing this wrong but I'm coming up blank.
Thanks for any clarification you folks can provide.
The problem is here:
node *temp = head->next;
while(temp != NULL)
temp = temp->next;
temp = newNode;
You're traversing the list, then setting temp to the value of the newNode. When temp goes out of scope, the value for newNode isn't stored anyplace.
What you want to do is set the next pointer of the last node to the value of newNode, i.e.
node *temp = head;
while(temp->next != NULL)
temp = temp->next;
temp->next = newNode;
The code above traverses the list until it finds a node that doesn't have a next node, and sets its next node to the newNode, thus adding it to the list.

Function moving list elements to the end of the list not working multiple times

I need to make a function that moves the nth element in a singly linked list to the end of the list. I created some code that does that but it only works once if I try to do it again it moves the selected element to the end but the one that was moved previously gets deleted/dissapears. My theory is that it doesnt actually change the tail reference. so im stuck right now!
void move(int n)
{
if (head == NULL || head->next == NULL)
{
return;
}
node *first = head;
node *temp =new node;
for (int i = 1; i < n-1; i++)
{
first=first->next;
}
temp = first->next;
first->next=first->next->next;
temp->next = NULL;
tail->next = temp;
tail=temp;
}
my input:
1 2 3 4 5
after moving the 3rd element for the first time:
1 2 4 5 3
after moving the 3rd element(4) for the 2nd time:
1 2 5 4
but it should be
1 2 5 3 4
I checked your code with my own implementation. Your function move() is working fine. However, you should not be using 'new' in your 8th line of code as highlighted by #molbdnilo and #PaulMakenzie. But it is not responsible for this problem. There is a problem with some other part of your code.
#include<iostream>
using namespace std;
class List
{
struct Node
{
int number;
Node* next;
};
Node* head;
Node* tail;
public:
List()
{
head = NULL;
tail = NULL;
}
void insert(int num)
{
Node* temp = new Node();
temp->number = num;
temp->next = NULL;
if (head == NULL)
{
head = temp;
tail = temp;
}
else
{
Node* point = head;
while (point->next != NULL)
point = point->next;
point->next = temp;
tail = point->next;
}
}
void display()
{
Node* point = head;
while (point != NULL)
{
cout << point->number << " ";
point = point->next;
}
}
void move(int n)
{
if (head == NULL || head->next == NULL)
{
return;
}
Node *first = head;
Node *temp;
for (int i = 1; i < n-1; i++)
{
first=first->next;
}
temp = first->next;
first->next=first->next->next;
temp->next = NULL;
tail->next = temp;
tail=temp;
}
};
int main()
{
List a;
a.insert(1);
a.insert(2);
a.insert(3);
a.insert(4);
a.insert(5);
a.move(3);
a.move(3);
a.display();
}

deleting a linked list node, C++ function not working

#include <iostream>
using namespace std;
class List {
public:
struct node {
int data;
node *next;
};
node* head = NULL;
node* tail = NULL;
node* temp = NULL;
node* prev = NULL;
public:
void addNum(int num) {
temp = new node;
temp->data = num;
temp->next = NULL;
if (head == NULL) {
head = temp;
tail = temp;
}
else {
tail->next = temp;
tail = temp;
}
}
void PrintList() {
temp = head;
while (temp != NULL) {
cout << temp->data << endl;
temp = temp->next;
}
}
void DelNum(int num) {
temp = head;
while (temp != NULL) {
if (temp->data == num) {
prev->next = temp->next;
free(temp);
}
temp = prev;
temp = temp->next;
}
}
};
int main() {
List list;
list.addNum(1);
list.addNum(2);
list.addNum(3);
list.addNum(4);
list.addNum(5);
list.addNum(6);
list.DelNum(3);
list.PrintList();
return 0;
}
What is wrong with my DelNum function? When I run the program nothing pops up. Doesn't matter what number I put in.
As mss pointed out the problem is in your DelNum() function where you assign temp = prev;. In your initialization you defined that node* prev = NULL; So, prev = NULL at the point when you assigned it to temp which caused segmentation fault when you try to use it like temp = temp->next;.
Two main problems are there in DelNum function:
first, when you are in while loop
, you should assign
prev = temp;
second, when you have found your target element, after deleting it you have to break out of the loop, which isn't done in your code
below is your corrected code( also correction of some other corner case in DelNum function ):
#include <iostream>
using namespace std;
class List {
public:
struct node {
int data;
node *next;
};
node* head = NULL;
node* tail = NULL;
node* temp = NULL;
node* prev = NULL;
public:
void addNum(int num) {
temp = new node;
temp->data = num;
temp->next = NULL;
if (head == NULL) {
head = temp;
tail = temp;
}
else {
tail->next = temp;
tail = temp;
}
cout<<num<<" is added \n";
}
void PrintList() {
temp = head;
while (temp != NULL) {
cout << temp->data << endl;
temp = temp->next;
}
}
void DelNum(int num) {
if(head==NULL)//empty
{
cout<<"empty linked list, can't be deleted\n";
return;
}
if(head->next==NULL)//means only one element is left
{
if(head->data==num)
{
node * fordelete=head;
head=NULL;
cout<<num<<"is deleted\n";
delete(fordelete);
}
else
{
cout<<"not found , can't be deleted\n";
}
return;
}
temp = head; // when more than one element are there
prev = temp;
while (temp != NULL) {
if (temp->data == num) {
prev->next = temp->next;
free(temp);
cout<<num<<" is deleted\n";
break;
}
prev= temp;
temp = temp->next;
}
if(temp==NULL)
{
cout<<"not found, can't be deleted\n";
}
}
};
int main() {
List list;
list.addNum(1);
list.addNum(2);
list.addNum(3);
list.addNum(4);
list.addNum(5);
list.addNum(6);
list.PrintList();
list.DelNum(3);
list.DelNum(7);
list.PrintList();
return 0;
}
I hope it will help you.

Linked list not working for input

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!