Insertion in Singly Linked List running on infinite loop - c++

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
}

Related

Delete nodes at positions divisible by 5 in linked list

I'm trying to delete every node at positions divisible by 5. With my approach I cannot seem to delete the last node:
void removeDivFive(Node* head){
int count = 0;
Node* temp = head;
while(temp != NULL){
count++;
if(count%5==0){
if(temp->next != NULL){
temp->value = temp->next->value;
temp->next = temp->next->next;
}
}
temp = temp->next;
}
while(head != NULL){
cout<<head->value;
head = head->next;
}
}
What I'm doing is copying the value of the next node to the current one and changing the pointer to the next next node. By doing this I cannot delete the last node if the list has 10 nodes.
Any help would be appreciated
First off, you are leaking the nodes you "remove". You need to actually destroy them since they are no longer being used.
Now, regarding your actual problem - what do you thing temp->next points at when the last node in the list is at a position divisible by 5? NOTHING! Thus, if (temp->next != NULL) evaluates as false, so you aren't even attempting to do anything with that last node, you just skip past it, which is why you are not removing it.
For every 5th node, you are copying the value of the next node into the current node, and then pointing the current node to skip the next node. In other words, you are not removing the 5th, 10th, 15th, etc nodes at all. You are actually removing the 6th, 11th, 16th, etc nodes instead. You need to remove the current node instead of the next node.
Which also means, you need to keep track of the previous node in the list so that you can re-link its next pointer to point at the next node that follows the current node being removed.
Try something more like this instead:
void removeDivFive(Node* head){
int count = 0;
Node *temp = head, *prev = NULL, *next;
while (temp != NULL){
++count;
next = temp->next;
if ((count % 5) == 0){
if (prev != NULL) {
prev->next = next;
}
delete temp;
}
else {
prev = temp;
}
temp = next;
}
}
Online Demo
Alternatively (as described by #GoswinvonBrederlow in comments):
void removeDivFive(Node* head){
int count = 0;
Node *temp = head, *next;
while (temp != NULL){
++count;
if ((count %4) == 0){
if (temp->next != NULL){
next = temp->next->next;
delete temp->next;
temp->next = next;
}
}
temp = temp->next;
}
}
Online Demo
As mentioned in the comments the deleted node isn't counted. So you need to delete a node every 4 counts instead of every 5. And if you use count%4 == 0 then the first time temp will point at node 4 and you want to delete the 5th node. So no need for temp->value = temp->next->value;, just remove the next node. Then next time around when count = 8 then temp will point at node 9. So again temp->next is the node to remove. ...
So the condition always fires for the node before the 5th, which is perfect for removing it.
void removeDivFive(Node* head){
int count = 0;
for (Node* temp = head; temp != NULL; temp = temp->next) {
count++;
if(count%4==0){
if(temp->next != NULL){
Node *t = temp->next;
temp->next = t->next;
delete t;
}
}
}
while(head != NULL){
cout<<head->value;
head = head->next;
}
}

LInked list not reversing

Bellow, I have some code that is supposed to display a linked list, reverse it, and then display the now reversed linked list, but it seems that it never displays. My only guess is that somehow the linked list is becoming null. What am I doing wrong? Both the reverse function and the function that should display the reversed array run, but there is no visual output after.
#include <iostream>
using namespace std;
class Node{
public:// creation of a simple Node class
int data;
Node* next;
};
class LinkedList{
public:
Node* head;
LinkedList() { head = NULL; }
void append( int x){
Node* temp = new Node;// allocate new node
Node* end = head;//used later
temp->data = x;//giving the node data
temp->next = NULL;//since this node will be last make the next of it NULL
if(head == NULL){// if list is empty then set new Node as the head
head = temp;
return;
}
while(end->next != NULL){// go until the last node
end = end->next;
}
end->next = temp;// change the next of the last node to the new node.
}
void reverse(){
Node* current = head;
Node* next = NULL;
Node* prev = NULL;
while(current != NULL){
next = current->next;// Store next
current->next = prev;// Reverse current node's pointer
prev = current;// Move pointers one position ahead.
current = next;
}
head = prev;
}
void display(){
while(head != NULL){// print data while not out of bounds
cout<<" "<<head->data;
head = head->next;
}
}
};
int main() {
LinkedList list;
list.append(1);
list.append(10);
list.append(32);
list.append(64);
list.append(102);
list.append(93);
list.display();
cout<<endl;
list.reverse();
cout<<"list reversed"<<endl;
list.display();
cout<<"reverse display ran"<<endl;
Turns out it was an oversight on my part, I should have set up a temporary variable that represented the head, in my current program I'm changing what head references in order to loop through the linked list, and thus setting head equal to null once it reaches the end of the list a correct way to write the display function would be:
void display(){
Node* temp = head;
while(temp != NULL){// print data while not out of bounds
cout<<" "<<temp->data;
temp = temp->next;
}
}
thanks to user Retired Ninja for reminding me that debuggers exist.

Strange behaviour when I am trying to implement my linked list in c++

I'm trying to implement my singly linked list , and I have this problem:
When I'm trying to pushBack some elements in my linked list , it will print only the first one which I added.For example , if I try to pushBack 2,3,4 - it will print only 2.
In case if I want to pushUp some elements in my linked list , it will print only the third one which I added. For example , if I try to pushUp 2,3,4 - it will print only 4.
This is my code:
enter code here
#include<iostream>
#include<vector>
using namespace std;
struct Node {
int data;
Node* next;
};
class LinkedList {
private:
// Create pointers for head and tail
Node *head , *tail;
public:
LinkedList(){
// Initiate them as null pointers
head = NULL;
tail = NULL;
}
public:
void pushBack(int value){
// Should add a node at the end of the linked list
Node* temp = new Node(); // temporary node which should be added
temp->data = value; // value to store
temp->next = NULL; // pointer to the next node
if(head != NULL){
// If there are some elements , then
temp->next = tail->next;
tail = temp;
}
if(head == NULL){
// If there are no elements , our node will be a head and a tail in the same time.
head = temp;
tail = temp;
}
}
void pushUp(int value){
// Shound add a node at the beginning of the linked list
Node* temp = new Node();
temp->data = value;
temp->next = NULL;
if(head == NULL){
// If there are no elements , our node will be a head and a tail in the same time.
head = temp;
tail = temp;
}
if(head != NULL){
// If there are some elements , just make our node to be new head.
temp->next = head->next;
head = temp;
}
}
void traversal(){
Node *temp = new Node();
temp = head;
while(temp != NULL){
cout << temp->data << " ";
temp = temp->next;
}
}
};
int main(){
// Pointer for our first node.
LinkedList a;
a.pushUp(2);
a.pushUp(124);
a.pushUp(3);
// a.pushBack(2);
// a.pushBack(124);
// a.pushBack(3); // Outputs only 2
a.traversal(); // Outputs only 3
}
You are missing edge cases. When you add the first node you are pointing it via head and tail ok but then you should check if there is only one node by comparing the address. And you should consider it for both function because if there is only one node head tail will change or head will be overwritten in your code.

class LinkedList {
private:
// Create pointers for head and tail
Node *head , *tail;
public:
LinkedList(){
// Initiate them as null pointers
head = NULL;
tail = NULL;
}
public:
void pushBack(int value){
// Should add a node at the end of the linked list
Node* temp = new Node(); // temporary node which should be added
temp->data = value; // value to store
temp->next = NULL; // pointer to the next node
if(head != NULL){
// If there are some elements , then
if(tail!=NULL){
tail->next = temp;
}else {
tail = temp;
head->next = tail;
}
}else {
// If there are no elements , our node will be a head and a tail in the same time.
head = temp;
}
}
void pushUp(int value){
// Shound add a node at the beginning of the linked list
Node* temp = new Node();
temp->data = value;
temp->next = NULL;
if(head == NULL){
// If there are no elements , our node will be a head and a tail in the same time.
head = temp;
}else {
// If there are some elements , just make our node to be new head.
if(tail != NULL){
temp->next = head;
head = temp;
}else {
tail = head;
head = temp;
temp->next = tail;
}
}
}
void traversal(){
Node *temp = new Node();
temp = head;
while(temp != NULL){
cout << temp->data << " ";
temp = temp->next;
}
}
};

```

C++ Double Linked List Reverse Print

I am trying to write a reverse print function as part of a doubly linked list. Here are the relevant functions that I have written:
void PLAYER::AddNode(int addID, std::string addName){
nodePtr n = new node; //creates a new node pointer
n->next = NULL; //Make next null
n->prev = NULL; // this will set this to be the ending node
n->ID = addID; //These two lines pass the information into the node
n->name = addName; // ID# and Name Information
if(head != NULL){ // This checks to see if a list is set up.
curr = head; // Make this point to the head.
while(curr->next != NULL){ // Loops through until the NULL is found
curr = curr->next;
}
curr->next = n; //Make the currnet node point to N
n->prev = curr; //Make the previous node connect to curr
n->next = tail; // connect new node to the tail.
}
else{
head = n; //If there is no list, this makes N the first node.
}
Here is the class that prototypes the functions to be used.
class PLAYER
{
public: // Functions go inside PUBLIC
PLAYER();
void AddNode(int addID, std::string addName);
void DeleteNode(int delPlayer);
void SortNode();
void PrintList();
void InsertHead(int AddID, std::string addName);
void PrintReverse();
private: //Variables go into here
typedef struct node{
// ...
std::string name;
int ID;
node* next;
node* prev;
}* nodePtr;
nodePtr head, curr, temp, prev, test, tail;
};
And finally my attempt to create a reverse traversing function to print backwards.
void PLAYER::PrintReverse()
{
curr = head;
while(curr->next != NULL) //Get to the end of the list
{
curr = curr->next;
}
while(curr->prev != NULL) //Work backward and print out the contents
{
std::cout << curr->ID << " " << curr->name << endl;
curr = curr->prev;
}
}
What I would like to do is inside the PrintReverse() function have it initialize via the tail pointer, however I can not figure out the functions to add to PrintReverse() and to AddNode() in order to have the new nodes pointed to by tail.
This is my first question posting here, I hope I covered all my bases. Thank you for any help I can find.
EDIT:
Thank you for all your input. I am relearning data structures and yes this is some self imposed homework on my part to begin to get the logic flowing again.
I will make the changes when I get home tonight.
The following changes would need to be considered.
The PrintReverse function would not need the forward pass to obtain the tail.
void PLAYER::PrintReverse()
{
curr = tail;
while(curr != NULL) //Work backward and print out the contents
{
std::cout << curr->ID << " " << curr->name << endl;
curr = curr->prev;
}
}
There is a problem in how tail is handled in the AddNode function. See the lines where the comments contain [CHANGED] and [ADDED]:
if(head != NULL){ // This checks to see if a list is set up.
curr = head; // Make this point to the head.
while(curr->next != NULL){ // Loops through until the NULL is found
curr = curr->next;
}
curr->next = n; //Make the currnet node point to N
n->prev = curr; //Make the previous node connect to curr
n->next = NULL; // [CHANGED]: we want the last node not to have a successor.
}
else{
head = n; //If there is no list, this makes N the first node.
}
tail = n; // [ADDED]: the last node added is the new tail.
However, a simpler solution is to avoid again the forward pass, and start from tail.
if(tail != NULL){ // This checks to see if a list is set up.
tail->next = n; //Make the old tail node point to N
n->prev = tail;
n->next = NULL;
}
else{
head = n; //If there is no list, this makes N the first node.
}
tail = n; // The last node added is the new tail.

Making a simple linked list in C++

struct Node{
string val;
Node* next;
};
Node* makeList ()
{
string current;
Node* n;
Node* head= NULL;
Node* temp = n;
while(cin>>current && !cin.fail())
{
n = new Node;
n->val = current;
temp ->next = n;
temp = temp -> next;
}
n->next = NULL;
return n;
}
I am trying to learn about linked lists, and this function makeList() is supposed to create and return a linked list using input from a list of strings. To be honest, I'm kind of lost. Any help would be greatly appreciated.
First of all, you are returning the last node of the linked list.. I think you should return the head and assign it to the first Node.
Secondly you are using cin.fail() for a string which I think should not be done. cin.fail() will work if there is a data mismatch and for string I think it is rare.
The function would look somewhat like:
Node* makeList ()
{
string current;
Node* n;
Node* head= NULL;
Node* temp = n;
while(cin>>current && !cin.fail())
{
if(current == "0")
break;
n = new Node;
n->val = current;
temp ->next = n;
temp = temp -> next;
if(!head)
head = n;
}
n->next = NULL;
return head;
}
First of all, since your temp represents the last element I would put it to NULL at the beginning (nullptr is more in the spirit of C++, so I'll use it in the text that comes).
After that in a while loop ,when you are adding a new element, you should write n->next=nullptr,since the pointer next of the new element(if you're always adding it to the back of the list) will always point to nullptr. In your implementation your new element n is always pointing to itself.Later on in your while loop you need to check if head==nullptr, if that's true than you should assign head to the new element that you made head=n. If head is not equal to nullptr then you need to add your element n to the back temp->next=n. An at the and of the loop you should assign the n element as last-temp=n (that has to be outside of the else block since it is done in both of the above mentioned cases).
I'm afraid answers above all got some bugs...
Node *make_link_list_from_input(){
string value;
Node *head = nullptr;
Node *current = nullptr;
Node *last = nullptr;
while (cin >> value){
current = new Node();
if(head== nullptr){
head = current;
}
if(last!= nullptr){
last->next=current;
}
last=current;
}
if(last != nullptr) {
last->next = nullptr;
}
return head;
}