Only Printing the First Value of Linked List - c++

I have no idea why display function is not displaying anything other than the first node's data. I've tried switching the While(p!=NULL) to while(p->next!= NULL but when I do that instead of only the first node's data displaying no data is being displayed.
#include <iostream>
using namespace std;
class Node {
public:
int no;
Node* next;
};
Node* createNode(int no1) {
Node* n = new Node();
n->no = no1;
n->next = NULL;
return n;
}
void addValue(int x, Node** head) {
//insert first node into linked list
Node* n = createNode(x),*p = *head;
if (*head == NULL) {
*head = n;
}
//insert second node onwards into linked list
else {
while (p->next!= NULL) {
p->next = n;
p = p->next;
}
}
}
void display(Node *head) {
Node* temp = head;
// temp is equal to head
while (temp->next!=NULL) {
cout << temp->no;
temp = temp->next;
}
}
int main() {
int num; char choice;
Node* head = NULL;
do {
cout << "Enter a number : ";
cin >> num;
addValue(num,&head);
cout << "Enter [Y] to add another number : ";
cin >> choice;
} while (choice == 'Y');
cout << "List of existing record : ";
display(head);
return 0;
}
I've tried changing the contents fo the else while loop in the addRecord function to p = p->next; p->next = n; in that order to no avail.

In the while loop, it should be
while (p->next!= NULL) {
p = p->next;
}
p->next = n;
Traverse until the end of linked list is reached and then, add the new entry.

Related

SIGSEV in Singly Linked List

I am writing a code to rotate a singly linked list counter-clockwise by K number of nodes. I wrote the following code. For example for the input linked list, 1,2,3,4,5,6,7,8 the rotate function Node *rotate(Node *head, int k){} returns the head pointer to the linked list 5,6,7,8,1,2,3,4. I wrote the following code. In this code, If I call print(head) inside the rotate function then it gives correct output but once it returns the head pointer to main then it either throws SIGSEV or is producing 1,2,3,4.
#include <iostream>
using namespace std;
class List {
public:
int data;
List *next;
explicit List(int element) : data(element), next(nullptr){}
};
List *insert() {
int n, i, value;
List *temp = nullptr, *head = nullptr;
cin >> n;
for(i = 0; i < n; ++i) {
cin >> value;
if(i == 0) {
head = new List(value);
temp = head;
continue;
} else {
temp ->next = new List(value);
temp = temp->next;
}
}
return head;
}
void print(List *start) {
while(start != nullptr) {
cout << start ->data << " ";
start = start->next;
}
}
List* rotate(List* head, int k) {
List *traverse = head, *temp = head;
List *kth, *end;
int i = 0;
while(i < k - 1) {
traverse = traverse ->next;
++i;
}
kth = traverse;
while(traverse->next != nullptr) {
traverse = traverse->next;
}
end = traverse;
head = kth->next;
kth->next = nullptr;
end->next = temp;
print(head);
return head;
}
int main() {
int k;
List *head = insert();
cin >> k;
print(head);
cout << endl;
rotate(head, k);
print(head);
return 0;
}
PS: I am only allowed to change the rotate function.

How to remove a certain node from a linked list by the data its holding?

We are suppose to enter a string, and then find where the string is in the linked list and remove that node
when i insert to the front of the list, so i enter data values a, b, c , d, when i print it it comes up as d,c,b,a. Now i insert to the rear of it, entering f and g, and the list now looks, d,c,b,a,f,g. I want to remove f but it just use the remove function it does not and still output the same list
using namespace std;
struct node {
string data;
node* next;
};
node* addFront(node* s);
node* addRear(node* s);
void remove(node* head, string abc);
void print(node* head);
int main() {
node* head = NULL;
cout << "Enter 5 data strings\n";
cout << "This will be inserted from the back\n";
for (int i = 0; i < 5; i++) {
head = addFront(head);
}
print(head);
cout << "Enter 3 strings and this will be inserted from the back of the orignal string\n";
for (int i = 0; i < 3; i++) {
head = addRear(head);
}
print(head);
cout << "Removing the head node\n";
string n;
cout << "Enter a string to remove\n";
cin >> n;
remove(head, n);
print(head);
}
node* addFront(node* s)
{
node* person = new node;
cin >> person->data;
person->next = s;
s = person;
return s;
}
node *addRear(node*s ) {
node* person = new node;
cin >> person->data;
person->next = NULL;
if (s == NULL) {
return person;
}
else {
node* last = s;
while (last->next != NULL) {
last = last->next;
}
last->next = person;
}
return s;
}
void remove(node* head, string a) {
node* previous = NULL;
node* current = head;
if (current == NULL) {
cout << "Value cannot be found\n";
return;
}
else {
while (previous != NULL) {
if (current->data == a) {
previous->next = current->next;
delete current;
break;
}
current = current->next;
}
}
}
void print(node * head)
{
node* temp = head;
while (temp != NULL) // don't access ->next
{
cout << temp->data << " ";
temp = temp->next;
}
cout << endl;
}
In remove function, previous is most certainly NULL when you hit that while loop.
Perhaps consider a do-while loop instead (with better handling of previous).
You may be better off handling the first node in a different manner since the holder of its previous is essentially the root pointer.

inserting node in the beginning of linked list using codeblocks

when i am inserting node in the beginning of the linked list, node is inserted in the beginning and is displayed. if i call display separately then it does not work and for inserting node at specific loc and at the end, calling display function works well.
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
typedef struct node {
int data;
struct node* next;
} node;
node* create(int n)
{
node* temp = NULL;
node* head = NULL;
node* p;
int i;
for (i = 0; i < n; i++) {
temp = (node*)malloc(sizeof(node));
cout << "enter the data for node number " << i << endl;
cin >> temp->data;
temp->next = NULL;
if (head == NULL) {
head = temp;
}
else {
p = head;
while (p->next != NULL) {
p = p->next;
}
p->next = temp;
}
}
return head;
}
node* insertatbeg(node* head)
{
node* temp = NULL;
temp = (node*)malloc(sizeof(node));
cout << "\nenter the data for first node" << endl;
cin >> temp->data;
temp->next = head;
head = temp;
return head;
}
void display(node* head)
{
node* t = NULL;
t = head;
while (t != NULL) {
cout << t->data << "->";
t = t->next;
}
}
node* insertatspecloc(node* head)
{
int n;
node* temp = NULL;
node* t = head;
temp = (node*)malloc(sizeof(node));
cout << "enter the data of node after which you want to insert the
node "<<endl;
cin
>> n;
cout << "\nenter the data for last node" << endl;
cin >> temp->data;
while (t->data != n) {
t = t->next;
}
temp->next = t->next;
t->next = temp;
return head;
}
node* insertatend(node* head)
{
node* temp = NULL;
temp = (node*)malloc(sizeof(node));
cout << "\nenter the data for last node" << endl;
cin >> temp->data;
temp->next = NULL;
node* q;
q = head;
while (q->next != NULL) {
q = q->next;
}
q->next = temp;
return head;
}
int main()
{
int n, a;
struct node* head = NULL;
cout << "enter the number of nodes u want to add";
cin >> n;
head = create(n);
display(head);
cout << "\npress 1 to add node at the beginning";
cout << "\npress 2 to add node at the specific location";
cout << "\npress 3 to add node at the end\n";
cin >> a;
if (a == 1) {
insertatbeg(head);
cout << "\nlinked list after insertion:\n";
display(head);
}
if (a == 2) {
insertatspecloc(head);
cout << "\nlinked list after insertion:\n";
display(head);
}
if (a == 3) {
insertatend(head);
cout << "\nLinked list after insertion:\n";
display(head);
}
}
When you are calling insertatbeg(head); the copy of head pointer is passed as the argument of your function, then in function you are modyfing local variable (copy of head)
node *insertatbeg(node *head)
{
node *temp=NULL;
temp=(node*)malloc(sizeof(node));
cout<<"\nenter the data for first node"<<endl;
cin>>temp->data;
temp->next=head;
head=temp; // assign to local variable <---
return head;
}
and for this reason after executing insertatbeg head is not updated. insertatbeg returns pointer so you can resolve your issue by calling
head = insertatbeg(head);
or you can call function in above line without assigning but then you should pass head by reference to be able to modify original passed object in function:
node *insertatbeg(node *& head) // pass pointer by reference
{
node *temp=NULL;
//...
head = temp; // now it works

Linked Lists Program Crashes After Receiving Values from User

My program is meant to run several functions, insertnode takes values from the user and creates a list of them using nodes and sorts them in order from least to greatest, printlist prints the values separated by spaces, mergelist merges the two lists in order, and reverselist reverses the list. The command prompt accepts values but once the stopping condition (0) is entered for the second list it crashes. Visual Studio shows no errors. I figure something is either wrong with the functions or the pointers. Someone spoke to me of a memory leak but Im unsure as to how to fix that.
#include <iostream>
#include <stack>
using namespace std;
class node {
private:
double num;
node *link;
public:
node() { }
node(double m, node *n) { num = m; link = n; }
node* getlink() { return link; }
double getdata() { return num; }
void setdata(double m) { num = m; }
void setlink(node* n) { link = n; }
};
typedef node* nodeptr;
void insertnode(nodeptr& head, double m);
void printlist(nodeptr head);
nodeptr mergelists(nodeptr& head1, nodeptr& head2);
void reverselist(nodeptr& head);
int main()
{
double input;a
nodeptr head1 = NULL; // Pointer to the head of List #1
nodeptr head2 = NULL; // Pointer to the head of List #2
nodeptr temp;
// Part 1 - Create two sorted lists
cout << "-------------------------------------" << endl;
cout << "CREATE LIST #1: " << endl;
cout << "-------------------------------------" << endl;
do {
cout << "Enter value (0 to quit): ";
cin >> input;
insertnode(head1, input);
} while (input != 0);
cout << "-------------------------------------" << endl;
cout << "CREATE LIST #2: " << endl;
cout << "-------------------------------------" << endl;
do {
cout << "Enter value (0 to quit): ";
cin >> input;
insertnode(head2, input);
} while (input != 0);
// Part 1 - Print the lists to make sure that they are correct.
printlist(head1);
printlist(head2);
// Part 2 - Merge the two lists and display the new merged list
temp = mergelists(head1, head2);
printlist(temp);
// Part 3 - Reverse the merged list and then display it
reverselist(temp);
printlist(temp);
return 0;
}
void insertnode(nodeptr& head, double m){
nodeptr p = head;
nodeptr k = p;
if (!p){
nodeptr n = new node(m, NULL);
}
else {
while (m >= p->getdata()){
k = p;
p = p->getlink();
}
nodeptr n = new node;
n->setdata(m);
k->setlink(n);
if (p){
n->setlink(p);
}
}
}
void printlist(nodeptr head){
nodeptr p = head;
while (p){
double m = p->getdata();
cout << m << " ";
p = p->getlink();
}
cout << endl;
}
nodeptr mergelists(nodeptr &head1, nodeptr &head2){
nodeptr result = 0, last = 0;;
if (head1->getdata() <= head2->getdata()){
result = head1;
head1 = head1->getlink();
}
else {
result = head2;
head2 = head2->getlink();
}
last = result;
while (head1 && head2){
if (head1->getdata() <= head2->getdata()){
last->setlink(head1);
last = head1;
head1 = head1->getlink();
}
else{
last->setlink(head2);
last = head2;
head2 = head2->getlink();
}
}
if (head1)
last->setlink(head1);
else if (head2)
last->setlink(head2);
last = 0;
head1 = 0;
head2 = 0;
return result;
}
void reverselist(nodeptr& head){
stack<double> holder;
nodeptr p = head;
while (p){
holder.push(p->getdata());
p = p->getlink();
}
p = head;
while (p){
p->setdata(holder.top());
holder.pop();
p = p->getlink();
}
}
There are a few issues with this method:
void insertnode(nodeptr& head, double m){
nodeptr p = head;
nodeptr k = p;
if (!p)
{
head = new node(m, NULL); // Update head
}
else
{
while (p && m >= p->getdata()) // Check for p!=NULL
{
k = p;
p = p->getlink();
}
nodeptr n = new node;
n->setdata(m);
k->setlink(n);
if (p)
{
n->setlink(p);
}
}
}
The simplified version:
void insertnode(nodeptr& head, double m)
{
nodeptr p = head;
nodeptr k = nullptr;
while (p && m >= p->getdata())
{
k = p;
p = p->getlink();
}
if (!k)
{
head = new node(m, p);
}
else
{
k->setlink(new node(m, p));
}
}
There are two issue is that you are not updating the head node when you insert into the linked list. The previous answer by #uncletall outlined this.
The second issue is very simple -- you failed to initialize the link to NULL when you default construct a node. Make the following change in your node class:
class node {
private:
double num;
node *link;
public:
node() : link(0) { } // here is the change here
//...
//... the rest of your code
};
When you default construct a node the link is now initialized. Without this change, your link node was a garbage value, thus you were not traversing the links properly when you were inserting more items in the list.
The change is similar to (but not exactly) the same as this:
class node {
private:
double num;
node *link;
public:
node() { link = 0; } // here is the change here
//...
//... the rest of your code
};
The difference is that link is assigned in the body of the constructor here, while the first example initializes the link to 0 before the constructor has started. Both wind up doing the same thing.

My linked lists program works, but it wont show all of the list

My linked lists program works, but it wont show all of the list
here is my code
When the user enters a name and contribution it stores it in the list. When i print out the list only the last name that the user entered showed. I think its in my AddToList function is the problem Thanks
#include <string>
using namespace std;
struct PersonRec
{
char aName[20];
//string aName;
int aBribe;
PersonRec* link;
};
class PersonList
{
private:
PersonRec *head;
bool IsEmpty();
public:
PersonList();
~PersonList();
void AddToList();
void ViewList();
};
#include <iostream>
#include <string>
using namespace std;
#include "personlist.h"
PersonList::PersonList()
{
head = NULL;
}
PersonList::~PersonList()
{
PersonRec *current, *temp;
current = head;
temp = head;
while(current != NULL)
{
current = current->link;
delete temp;
temp = current;
}
}
bool PersonList::IsEmpty()
{
//PersonRec *p;
if(head == NULL)//it has no nodes head will poin to NULL
{
return true;
}
else
{
//p = head;
return false;
}
}
void PersonList::AddToList()
{
PersonRec *p;
head = new PersonRec();
//if(head == NULL)
//{
if(!IsEmpty())
{
//head = new PersonRec();
cout<<"Enter the person's name: ";
cin.getline(head->aName, 20);
//cin>>head->aName;
cout<<"Enter the person's contribution: ";
cin>>head->aBribe;
//head->link = NULL;
//}
}
else
{
p = head;
while(p->link != NULL)
p = p->link;
p->link = new PersonRec();
}
}//end function
void PersonList::ViewList()
{
PersonRec *p;
p = head;
if(IsEmpty())
{
cout<<"List is Empty "<<endl;
}
while(p != NULL)
{
cout<<p->aName<<" "<<"$"<<p->aBribe<<endl;
p = p->link;
}
}
#include <iostream>
#include "personlist.h"
using namespace std;
int displayMenu (void);
void processChoice(int, PersonList&);
int main()
{
int num;
PersonList myList;
do
{
num = displayMenu();
if (num != 3)
processChoice(num, myList);
} while (num != 3);
return 0;
}
int displayMenu(void)
{
int choice;
cout << "\nMenu\n";
cout << "==============================\n\n";
cout << "1. Add student to waiting list\n";
cout << "2. View waiting list\n";
cout << "3. Exit program\n\n";
cout << "Please enter choice: ";
cin >> choice;
cin.ignore();
return choice;
}
void processChoice(int choice, PersonList& p)
{
switch(choice)
{
case 1: p.AddToList();
break;
case 2: p.ViewList();
break;
}
}
Think about it: head is a pointer to the first item in your list, and the first thing you do in AddToList() is:
head = new PersonRec();
What do you think is going to happen to the current list when you overwrite head in this manner?
Don't change head until you're ready. The basic pseudo-code would be:
newnode = new PersonRec; # Don't overwrite head yet.
# Populate newnode with payload.
newnode-> next = head # Put current list at end.
head = newnode # Now you can change it.
That's if you wanted the new node at the start of the list. If you want it at the end, it's a little more complicated since you either have to:
traverse the list looking for the last node so you can append the new node to it; or
keep a pointer to the last node as well, to avoid traversal.
But the detail remains the same: don't destroy your head pointer until such time as you have the current list accessible by some other means.
I should mention that, based on your commented out code in AddToList(), you appear to be very close. Setting head should be done in the case where isEmpty() is true. But you appear to have commented that out and moved the head = new ... bit to outside/before the if statement. Not sure exactly what happened there with your thought processes.
It looks like what you tries to do was along the lines of:
if isEmpty:
head = new PersonRec;
p = head
else:
p = head
while p->next != NULL:
p = p->next
p->next = new PersonRec;
p = p->next
# Here, p is a pointer to the new node (head or otherwise)
# and the list is stable
p-> payload/link = whatever/null
That last line is also important, and your code doesn't seem to do it in all cases (ie, other than when you're creating the initial node in the list).
Making that a little less language-agnostic would give you something like (untested):
void PersonList::AddToList() {
PersonRec *p;
if(!IsEmpty()) {
p = head = new PersonRec();
} else {
p = head;
while (p->link != NULL)
p = p->link;
p->link = new PersonRec();
p = p->link;
}
cout << "Enter the person's name: ";
cin.getline (p->aName, 20);
cout << "Enter the person's contribution: ";
cin >> p->aBribe;
p->link = NULL;
}