How do we display a linked list? - c++

So I created the following bit of code but the display function is giving me problems. It breaks into an infinite loop each time I try using it. Could someone please have a look at it and tell me what's going wrong ?
#include<iostream.h>
#include<conio.h>
struct node{
int info;
node *next;
}*ptr,*start,*temp;
node* create_new()
{
ptr=new node;
cout<<"\nEnter the data: ";
cin>>ptr->info;
ptr->next=NULL;
return ptr;
}
void insert_at_beg()
{
ptr=create_new();
if(start==NULL)
{
start=ptr;
}
if(start!=NULL)
{
ptr->next=start;
start=ptr;
}
}
void display()
{
temp=start;
while(temp->next!=NULL)
{
cout<<"\t"<<temp->info;
temp=temp->next;
}
}
void insert_at_end()
{
if(start==NULL)
{
start=ptr;
}
if(start!=NULL)
{
ptr=create_new();
temp=start;
while(temp->next!=NULL)
{
temp=temp->next;
}
temp->next=ptr;
}
}
void delete_from_end()
{
if(start==NULL)
{
cout<<"NULL LL";
}
else
{
temp=start;
while(temp->next!=NULL)
{
ptr=temp;
temp=temp->next;
}
ptr->next=NULL;
delete temp;
}
}
void delete_from_beg()
{
if(start==NULL)
cout<<"\nNULL LL";
else
start=start->next;
}
void delete_from_mid()
{
int el;
if(start==NULL)
{
cout<<"\nNULL LL";
}
else
{
cout<<"\nEnter element that you want to delete: ";
cin>>el;
temp=start;
while(temp->next!=NULL&&temp->info!=el)
{
ptr=temp;
temp=temp->next;
}
ptr->next=temp->next;
delete temp;
}
}
void main()
{
clrscr();
start=NULL;
temp=NULL;
ptr=NULL;
insert_at_beg();
display();
getch();
}

Your bug is in this code:
void insert_at_beg()
{
ptr=create_new();
if(start==NULL)
{
start=ptr;
}
if(start!=NULL)
{
ptr->next=start;
start=ptr;
}
}
The first time in start will be null, so you'll do start=ptr. However, now if(start!=NULL) will be true, so you'll do ptr->next=start. Since ptr and start both point to the same thing you'll create an infinite loop.

Firstly I would not recommend you to use global variables especially when you have functions that themselves output parameters of the same type (and value).
The problem according to me is in the function insert_at_beg():
// yes start is NULL initially
if(start==NULL)
{
start=ptr; // now start is not NULL!!
}
//This statement will also be entered.
if(start!=NULL)
{
ptr->next=start;
start=ptr;
}
}
Instead use an else
if(start==NULL)
{
start=ptr; // now start is not NULL!!
}
else
{
ptr->next=start;
start=ptr;
}
}
Also, instead of:
#include<iostream.h>
#include<conio.h>
Use just #include<iostream>

Your bug that cause infinite loop is somewhere else (insert_at_beg(), I saw that someone already added the details so I won't do this too) in the code.
You still have a problem in your code:
void display()
{
temp=start;
while(temp->next!=NULL)
{
cout<<"\t"<<temp->info;
temp=temp->next;
}
}
You will not print the last elemnt. You stop when the next of the current element (temp) is NULL.
Change this to
while(temp) // equivalent to while(temp !=NULL)

Your display function can be simplified:
void display()
{
node * p = start;
while (p != NULL)
{
cout << "\t" << p->info;
p = p->next;
}
cout << endl; // The side effect of this is to print blank line when empty list.
}

Related

I don't know why my insertion function is not working for the final insertion i.e. for value 5 plus swapping is also not working. Can anybody assist?

The problem in my code starts from the final insertion that I have tried in the main() followed by the swapping method. I don't understand why swapping is not working plus the fact that insertion just doesn't work for the last one simply blows my mind. Is anybody there to help me?
```
void LL::insertion(int info,int val) //insertion problem arises in the fifth insertion.
{
if(head==NULL)
{
cout<<"LL is empty!"<<endl;
Node *temp=new Node;
temp->data=val;
temp->next=NULL;
head=temp;
}
else
{
Node *temp=new Node;
temp->data=val;
query=head;
while(query->data!=info && query->next!=NULL)
{
query=query->next;
}
if(query->data==info)
{
temp->next=query->next;
query->next=temp;
}
else
{
cout<<"The value you entered is not found in the LL!"<<endl;
}
}
}
void LL::swapping(int info,int val) //swapping is not working.
{
if(head==NULL)
{
cout<<"LL is empty!"<<endl;
}
else
{
query=head;
Node *temp;
temp=query;
while(query->data!=info && temp->data!=val)
{
query=query->next;
temp=temp->next;
}
Node *temp1;
temp1=query;
query->next=temp->next;enter code here
temp->next=temp1->next;
delete temp1;
}
}
int main()
{
LL obj; //"obj" is object of of the class "LL"
//cout<<obj.emptiness()<<endl;
obj.insertion(0,1);
obj.insertion(1,2);
obj.insertion(2,3);
obj.insertion(3,4);
obj.insertion(4,5); //here problem arises.
obj.swapping(1,5); //no error is shown on compiler.
}
```

I am getting an segmentation fault error in line head=NULL

I didn't understand why i am getting error in line head=NULL I am just pointing head towards NULL
I have also tried creating a new node for head and then pointing towards NULL but still it doesn't work
Code show here
#include <bits/stdc++.h>
using namespace std;
struct node
{
int data;
node *next;
};
node *head=NULL;
node *tail=NULL;
void createnode(int value)
{
node *temp=new node;
temp->data=value;
temp->next=NULL;
if(head==NULL)
{
head=temp;
tail=temp;
temp=NULL;
}
else
{
tail->next=temp;
tail=temp;
}
}
void deletek(int n,int k)
{
if(head==NULL)
return;
node *temp;
temp=head;
while(temp->data<temp->next->data)
{
head=temp->next;
temp=temp->next;
k--;
}
while(temp!=NULL&&k!=0)
{
if(temp->next->data<temp->next->next->data)
{
temp->next=temp->next->next;
k--;
}
temp=temp->next;
}
}
void display()
{
node *temp=head;
while(temp!=NULL)
{
cout<<temp->data<<" ";
temp=temp->next;
}
cout<<endl;
}
int main() {
int t;
cin>>t;
int n,k;
for(int i=0;i<t;i++)
{
cin>>n>>k;
int arr[n];
for(int j=0;j<n;j++)
{
cin>>arr[j];
createnode(arr[j]);
}
deletek(n,k);
display();
head=NULL;
}
}
I expect that whenever the line head=NULL runs the previous linked list should get delete and I should be able to enter elements in the linked list from the beginning
First of all: C++ likes "nullptr" (since C++11) for this, instead of "NULL".
=> e.g. https://en.cppreference.com/w/cpp/types/NULL vs. https://en.cppreference.com/w/cpp/language/nullptr
Second: The exact compiler output could help.
Third: The list will not be deleted if you throw away the address of it's location. maybe you should rather create a class and/or add destructor for your node. If you want to implement LL by yourself
Or have a look at std::list -> https://en.cppreference.com/w/cpp/container/list. I use this rather often.
Or if you like to add boost dependency: https://www.boost.org/doc/libs/1_35_0/doc/html/intrusive/list.html more fancy but you'll add an external library
Then: The Segfault (on my PC) happens in if(temp->next->datanext->next->data) I guess you can never know if temp->next->next->data exists... maybe not even if temp->next->data => if temp->next points to NULL (or nullptr) it is not a valid instance of node to dereference
try:
`
#include <bits/stdc++.h>
#define HERE() printf("HERE: %d\n", __LINE__)
using namespace std;
struct node
{
int data;
node *next;
};
node *head=NULL;
node *tail=NULL;
void createnode(int value)
{
node *temp=new node;
temp->data=value;
temp->next=NULL;
if(head==NULL)
{
head=temp;
tail=temp;
temp=NULL;
}
else
{
tail->next=temp;
tail=temp;
}
}
void deletek(int n,int k)
{
if(head==NULL)
return;
node *temp;
temp=head;
while(temp->data<temp->next->data)
{
head=temp->next;
temp=temp->next;
k--;
}
HERE();
while(temp!=NULL&&k!=0)
{
HERE();
int d1 = temp->next->data;
HERE();
int d2 = temp->next->next->data;
if(temp->next->data < temp->next->next->data)
{
temp->next=temp->next->next;
k--;
}
temp=temp->next;
}
}
void display()
{
node *temp=head;
while(temp!=NULL)
{
cout<<temp->data<<" ";
temp=temp->next;
}
cout<<endl;
}
int main() {
int t;
cout << "input t:" << endl;
cin>>t;
int n,k;
for(int i=0;i<t;i++)
{
cout << "input n/k" << endl;
cin>>n>>k;
int arr[n];
for(int j=0;j<n;j++)
{
cout << "input arr[" << j <<"]" << endl;
cin>>arr[j];
createnode(arr[j]);
}
deletek(n,k);
display();
head=NULL;
}
}
`

deletion of a node in a singly linked list

I have made a program in c++ to delete a node in a singly linked list but it is not working as predicted. I am attaching pictures of the output for better clarity that whats misbehaving.
code:
int del_node(int val_del) //this section is producing error
{
node* temp_del=head;
if(head==nullptr)
{
cout<<"no element to delete.!";
exit(0);
}
else
{
while(temp_del->next!=nullptr)
{
if(temp_del->next->data==val_del)
{
temp_del->next=temp_del->next->next;
delete temp_del->next->next;
}
temp_del=temp_del->next;
}
}
return 0;
}
This a function of a class.
Here is the complete code if it helps:
#include<iostream>
using namespace std;
struct node
{
int data;
node *next;
};
class linked_list
{
node *head,*tail;
public:
linked_list()
{
head=nullptr;
tail=nullptr;
}
int create_last(int val_last)
{
node *temp=new node; if(!temp){cout<<"memory not allocated"; exit(1);}
temp->data=val_last;
temp->next=nullptr;
if(head==nullptr)
{
head=temp;
tail=temp;
}
else
{
tail->next=temp;
tail=temp;
}
return 0;
}
int create_beg(int val_beg)
{
node *temp_head=nullptr;
node *temp=new node; if(!temp){cout<<"memory not allocated"; exit(1);}
temp->data=val_beg;
temp->next=nullptr;
if(head==nullptr)
{
head=temp;
tail=temp;
}
else
{
temp_head=head;
head=temp;
temp->next=temp_head;
}
return 0;
}
int del_node(int val_del) //this section is producing error
{
node* temp_del=head;
if(head==nullptr)
{
cout<<"no element to delete.!";
exit(0);
}
else
{
while(temp_del->next!=nullptr)
{
if(temp_del->next->data==val_del)
{
temp_del->next=temp_del->next->next;
delete temp_del->next->next;
}
temp_del=temp_del->next;
}
}
return 0;
}
int show()
{
node* temp_show=head;
while(temp_show!=nullptr)
{
cout<<temp_show->data<<"\n";
temp_show=temp_show->next;
}
return 0;
}
}info;
int main()
{
int choice,ele; char cont;
rep:
cout<<"1. Insert node at the end\n";
cout<<"2. Insert node at beg\n";
cout<<"3. Delete node\n";
cout<<"4. Show nodes\n";
cout<<"5. Exit\n";
cout<<"enter your choice: ";
cin>>choice;
switch(choice)
{
case 1: cout<<"Enter element: ";
cin>>ele;
info.create_last(ele);
break;
case 2: cout<<"Enter element: ";
cin>>ele;
info.create_beg(ele);
break;
case 3: cout<<"Enter element: ";
cin>>ele;
info.del_node(ele);
break;
case 4: info.show();
break;
case 5: exit(0);
break;
default: cout<<"Wrong choice, Bye.!!";
exit(0);
}
cout<<"Do you want to continue(y/n): ";
cin>>cont;
if(cont=='y'||cont=='Y')
{
goto rep;
}
else
{
cout<<"thank you";
exit(0);
}
return 0;
}
int del_node(int val_del) {
node* temp_del = head;
if(head == nullptr) {
cout<<"no element to delete.!";
exit(0);
} else if(head->data == val_del) {
// If head is to be deleted
head = head->next;
} else {
while(temp_del->next != nullptr) {
if(temp_del->next->data == val_del) {
temp_del->next=temp_del->next->next;
// delete temp_del->next->next; This is wrong deletion
}
temp_del = temp_del->next;
}
}
// delete the node if one found else not
if (temp_del != nullptr)
delete temp_del;
return 0; // This should return true or false, do check what you want as return type
}
The del_node function has two problems:
1) It can't delete the node when the list has exactly 1 element
2) It deletes the wrong element
So let's start with number 1 and look at the code:
if(head==nullptr)
{
cout<<"no element to delete.!";
exit(0);
}
else
{
while(temp_del->next!=nullptr)
Assume that the list contains exactly one element. That means:
a) head is not NULL
b) head->next and therefore also temp_del->next is NULL
so while(temp_del->next!=nullptr) will result in false, i.e. the loop will no be executed. The overall result is that the code does nothing.
Now for number 2. The code is:
if(temp_del->next->data==val_del)
{
temp_del->next=temp_del->next->next; // You want to delete temp_del->next
// but here you change it
delete temp_del->next->next; // so here you delete the wrong node
// there is also an extra ->next
}
You need a temp variable to hold a pointer to the node you want to delete.
You probably want the code to be:
int del_node(int val_del)
{
// Delete elements in the front
while (head!=nullptr && head->data==val_del)
{
node* node_to_delete = head;
head = head->next;
delete node_to_delete;
// return 0; Uncomment if you only want one delete per function call
}
if(head==nullptr) return 0;
// Delete elements not in the front
node* temp_del=head;
while(temp_del->next!=nullptr)
{
if (temp_del->next->data==val_del)
{
node* node_to_delete = temp_del->next;
temp_del->next = temp_del->next->next;
delete node_to_delete;
// return 0; Uncomment if you only want one delete per function call
}
temp_del=temp_del->next;
}
return 0;
}

C++ merging two linked lists segmentation fault and core dump error

This is my code for merging two linked lists together. When I run it I get a segmentation fault and core dump error. I don't know how to fix it. My brain is fried please help.
#include<iostream>
using namespace std;
struct node
{
int data;
struct node *next;
};
class list
{
struct node *start;
public:
void create();
void show();
void merge(list,list);
};
void list::create()
{
struct node *nxt_node, *pre_node;
int value, no, i;
start=nxt_node=pre_node=NULL;
cout<<"\nHow many nodes:";
cin>>no;
cout<<"Enter "<<no<<" Eelements:";
for(i=1;i<=no;i++)
{
cin>>value;
nxt_node=new node;
nxt_node->data=value;
nxt_node->next=NULL;
if (start==NULL)
start=nxt_node;
else
pre_node->next=nxt_node;
pre_node=nxt_node;
}
}
void list::show()
{
struct node *ptr=start;
while(ptr!=NULL)
{
cout<<ptr->data<<"->'";
ptr=ptr->next;
}
}
void list::merge(list l1,list l2)
{
struct node *nxt_node, *pre_node, *pptr, *qptr;
int dat;
pptr=l1.start;
qptr=l2.start;
start=nxt_node=pre_node=NULL;
while(pptr!=NULL && qptr!=NULL)
{
if(pptr->data<=qptr->data)
{
dat=pptr->data;
pptr=pptr->next;
}
else
{
dat=qptr->data;
qptr=qptr->next;
}
nxt_node=new node;
nxt_node->data=dat;
nxt_node->next=NULL;
if(start==NULL)
{
start=nxt_node;
}
else
{
pre_node->next=nxt_node;
pre_node=nxt_node;
}
}
if(pptr==NULL)
{
while(qptr!=NULL)
{
nxt_node=new node;
nxt_node->data=qptr->data;
nxt_node->next=NULL;
if(start==NULL)
start=nxt_node;
else
pre_node->next=nxt_node;
pre_node=nxt_node;
qptr=qptr->next;
}
}
else if (qptr==NULL)
{
while(pptr!=NULL)
{
nxt_node=new node;
nxt_node->data=pptr->data;
nxt_node->next=NULL;
if(start==NULL)
start=nxt_node;
else
pre_node->next=nxt_node;
pre_node=nxt_node;
pptr=pptr->next;
}
}
}
int main()
{
list l1,l2,l3;
cout<<"Enter the first list in ascending order.";
l1.create();
cout<<"Enter the Second list in ascending order.";
l2.create();
cout<<"The first list is:"<<endl;
l1.show();
cout<<"The second list is"<<endl;
l2.show();
l3.merge(l1,l2);
l3.show();
return (0);
}
In the method merge
if(start==NULL)
{
start=nxt_node;
}
should be changed to
if(start==NULL)
{
start=nxt_node;
pre_node=start;
}
I think you can figure why.

Popping out a number from stack in c++?

my code so far is...
struct stack_struct
{
int number;
struct stack_struct *next_number;
};
stack_struct *mainStruct;
class stack_class
{
private:
struct stack_struct *head;
public:
stack_class();
~stack_class();
void pushNumber(int number);
void popNumber();
void findNumber();
void clearStack();
void sizeFinder();
void printStack();
void reverseStack();//Extra Credit
};
stack_class mainClassStack;
stack_struct *pointerFunc,*tailPointer=NULL,*pointerFunc3,*printPointer;
stack_class::stack_class()
{
head=NULL;
}
stack_class::~stack_class()
{
clearStack();
cout<<"\nList Cleared.\n";
system("pause");
}
void stack_class::popNumber()
{
stack_struct *pointerPop=NULL,*pointerPop2=NULL;
int popCounter=0,i=0;
pointerPop2=tailPointer;
if(head==NULL)
{
cout<<"\nNo Member to Delete.\n";
}
else
{
while(pointerPop2)
{
popCounter++;
//cout<<pointerFunc3->number<<endl;
pointerPop2=pointerPop2->next_number;
}
pointerPop=tailPointer;
while(i<(popCounter-2))
{
pointerPop=pointerPop->next_number;
i++;
}
pointerPop->next_number=NULL;
delete head;
head=pointerPop;
}
}
void stack_class::printStack()
{
pointerFunc3=tailPointer;
if(tailPointer==NULL)
{
cout<<"\nNo Members in List.\n";
}
else
{
cout<<"\n\nList Is:\n";
while(pointerFunc3)
{
cout<<pointerFunc3->number<<endl;
pointerFunc3=pointerFunc3->next_number;
}
}
}
Popping works fine as long as it is not the last number. If the last number is popped (list is empty), and I try to print the list, the program infinitely prints garbage. If I try to pop a number after the list is empty, the program freezes. How do I fix these?
You could also allways to create one dummy node for solve this. Otherwise:
int stack_class::popNumber()
{
if(head==NULL)
throw new Exception("Stack is empty");
int result = head->number;
delete head;
head = head->next_number;
return result;
}
void stack_class::pushNumber(int number)
{
stack_struct *elem= new stack_struct();
elem->number = number;
elem->next_number = head;
head = elem;
}
!!!!!try do not use globals variables like (stack_class mainClassStack;
stack_struct *pointerFunc,*tailPointer=NULL,)
Change your popNumber() like this,
void stack_class::popNumber()
{
stack_struct *pointerPop=NULL,*pointerPop2=NULL;
int popCounter=0,i=0;
pointerPop2=tailPointer;
if(head==NULL)
{
cout<<"\nNo Member to Delete.\n";
}
else if(head->next_number==NULL)
{
cout<<"\nThe Poped element is"<<head->number;
head=NULL;
}
else
{
// Your Code;
}
}
include cstdlib for exit
int Stack::pop()
{ if (top == NULL)
{
cerr <<"Stack is empty";
exit(1);
}
else
{
Node* zap = top;
top = zap->link;
int return_value = zap->n;
delete zap;
return return_value;
}
}
Qazi you have to put the if(top==NULL)check at the start of both procedures.