C++ Linked list issue - c++

I have been working on a little personal project, and have run into a snag. The purpose of the project is to add to my Github, but I have been staring at my code off and on for the last week and cannot find where it goes wrong. The project is a test of my own ability, and my understanding of Linked Lists in C++. Before I go on, here is my code
#include <iostream>
using namespace std;
struct payload {
int ID;
int x;
int y;
string name;
};
struct node {
node* prev;
node* next;
bool isRoot;
payload data;
};
node* fillStruct(node* tmp);
void print(node* tmp);
int main(void) {
node* temp;
node* list;
node* iterator;
bool done = false;
int count = 0;
char answer;
do {
temp = new node();
temp = fillStruct(temp);
if (count == 0) {
list = new node();
list = temp;
list->prev = NULL;
list->next = NULL;
list->isRoot = true;
} else {
list->next = temp;
temp->prev = list;
list = new node();
list = temp;
}
count++;
cout << "Will more elements be added to the list?\n [Y or N]\n";
cin >> answer;
switch (answer) {
case 'y':
case 'Y':
break;
case 'n':
case 'N':
list->next = NULL;
done = true;
break;
default:
break;
}
} while (!done);
while (list->prev != NULL) {
list = list->prev;
}
int identifier = 100;
while (1) {
list->data.ID = identifier;
identifier++;
if (list->next == NULL)
break;
list = list->next;
}
while (list->prev != NULL) {
list = list->prev;
}
while (1) {
print(list);
if (list->next == NULL)
break;
list = list->next;
}
return 0;
}
node* fillStruct(node* tmp) {
if (!tmp) {
cerr << "Unauthorized access. Terminating program";
return tmp;
}
cout << "Please enter the X value.\n";
cin >> tmp->data.x;
cout << "Please enter the Y value.\n";
cin >> tmp->data.y;
cout << "Please enter the data name\n";
cin >> tmp->data.name;
return tmp;
}
void print(node* tmp) {
cout << "Identifier: " << tmp->data.ID << endl;
cout << " X: " << tmp->data.x << endl;
cout << " Y: " << tmp->data.y << endl;
cout << " Name: " << tmp->data.name << endl;
}
The code compiles and executes fine. The problem I am having is in the printing phase of the code. It cuts off the last element, and I cannot tell why. The second while(1), as I understand it, should terminate after it prints the final element. If anyone can offer guidance, I would greatly appreciate it. Thanks in advance, and as usual, if there's anything I can add to clarify, I will.

Following your code, it would seem better to keep list at the list head, and use a pointer for walking the list.
node* list = NULL;
node* ptr = NULL; // tail
do {
temp = new node();
temp = fillStruct(temp);
temp->prev = ptr;
temp->next = NULL;
if (ptr) {
ptr->next = temp;
}
ptr = temp;
if (!list) {
list = ptr;
}
count++;
cout << "Will more elements be added to the list?\n [Y or N]\n";
cin >> answer;
switch (answer) {
case 'y':
case 'Y':
break;
case 'n':
case 'N':
done = true;
break;
default:
break;
}
} while (!done);
int identifier = 100;
for (ptr = list; ptr; ptr = ptr->next) {
ptr->data.ID = identifier;
identifier++;
}
for (ptr = list; ptr; ptr = ptr->next) {
print(list);
}

Related

Reverse Deque C++.Implementation based on linked list

I have implemented deque through linked list.
Below You can see my code:
#include <iostream>
using namespace std;
struct Node
{
int mData;
Node* pPrev, *pNext;
Node()
{
this->mData = mData;
pPrev = pNext = NULL;
}
Node(int value)
{
mData = value;
pPrev = pNext = NULL;
}
};
class Deque
{
private:
Node *pFront, *pRear;
int mSize;
public:
Deque()
{
pFront = pRear = NULL;
mSize = 0;
}
void pushFront(int data)
{
Node* newNode = new Node(data);
if (newNode == NULL)
{
cout << "Error";
}
else
{
if (pFront == NULL)
{
pRear = pFront = newNode;
}
else
{
newNode->pNext = pFront;
pFront->pPrev = newNode;
pFront = newNode;
}
mSize++;
}
}
void pushLast(int data)
{
Node* newNode = new Node(data);
if (newNode == NULL)
{
cout << "Error";
}
else
{
if (pRear == NULL)
{
pFront = pRear = newNode;
}
else
{
newNode->pPrev = pRear;
pRear->pNext = newNode;
pRear = newNode;
}
mSize++;
}
}
void deleteFront()
{
if (isEmpty())
{
cout << "Deque is empty";
}
else
{
Node* temp = pFront;
pFront = pFront->pNext;
if (pFront == NULL)
{
pRear = NULL;
}
else
{
pFront->pPrev = NULL;
}
free(temp);
mSize--;
}
}
void deleteLast()
{
if (isEmpty())
{
cout << "Deque is empty";
}
else
{
Node* temp = pRear;
pRear = pRear->pPrev;
if (pRear == NULL)
{
pFront = NULL;
}
else
{
pRear->pNext = NULL;
}
free(temp);
mSize--;
}
}
int getFront()
{
if (isEmpty())
{
cout << "Deque is empty";
}
else
{
return pFront->mData;
}
}
int getLast()
{
if (isEmpty())
{
cout << "Deque is empty";
}
else
{
return pRear->mData;
}
}
void swap()
{
if (isEmpty())
{
cout << "Deque is empty";
}
else
{
Node* temp = pFront;
while (temp->pNext != NULL) {
temp = temp->pNext;
}
Node* tmp2 = new Node();
tmp2->mData = temp->mData;
temp->mData = pFront->mData;
temp->pNext = NULL;
pFront->mData = tmp2->mData;
}
}
bool isEmpty()
{
return (mSize == 0);
}
int getSize()
{
return mSize;
}
void reverse()
{
auto curr = pFront; // current pointer
Node* prev = NULL; // previous pointer
while (curr) {
auto temp = curr->pNext;
curr->pNext = prev;
prev = curr;
pFront = prev;
curr = temp;
}
}
bool isBelong(int data)
{
Node* temp = pFront;
while (temp != NULL)
{
if (data == temp->mData)
{
return true;
}
temp = temp->pNext;
}
return false;
}
void clear()
{
pRear = NULL;
while (pFront != NULL)
{
Node* temp = pFront;
pFront = pFront->pNext;
delete temp;
}
pFront = NULL;
mSize = 0;
}
void show()
{
Node* node = pFront;
while (node != NULL)
{
cout << node->mData << " ";
node = node->pNext;
}
}
};
int main()
{
Deque deque; int num;
while (true)
{
int choice;
cout << "\n0.Exit.\n1.Insertion(head).\n2.Insertion(rear).\n3.Deletion(head).\n4.Deletion(rear).\n5.Get head.\n6.Get rear.\n7.Check emptyness.\n8.Check size.\n9.Clear deque.\n10.Swap front and rear.\n11.Check belonginess.\n12.Reverse deque.\n";
cin >> choice;
switch (choice)
{
case 0: return 0;
case 1:
cout << "Insertion to head - input value : "; cin >> num;
deque.pushFront(num);
deque.show();
system("pause");
system("cls");
break;
case 2:
cout << "Insertion to rear - input value : "; cin >> num;
deque.pushLast(num);
deque.show();
system("pause");
system("cls");
break;
case 3:
deque.deleteFront();
deque.show();
system("pause");
system("cls");
break;
case 4:
deque.deleteLast();
deque.show();
system("pause");
system("cls");
break;
case 5:
if (deque.isEmpty())
{
cout << "Deque is empty";
}
else
{
cout << "First element of deque : " << deque.getFront();
}
system("pause");
system("cls");
break;
case 6:
if (deque.isEmpty())
{
cout << "Deque is empty";
}
else
{
cout << "Last element of deque : " << deque.getLast();
}
system("pause");
system("cls");
break;
case 7:
if (deque.isEmpty())
{
cout << "Deque is empty";
}
else
{
cout << "Deque is not empty: "; deque.show();
}
system("pause");
system("cls");
break;
case 8:
cout << "Size of deque : " << deque.getSize();
system("pause");
system("cls");
break;
case 9:
deque.clear();
system("pause");
system("cls");
break;
case 10:
cout << "Deque before swap: "; deque.show(); cout << endl;
deque.swap();
cout << "Deque after swap: "; deque.show(); cout << endl;
system("pause");
system("cls");
break;
case 11:
cout << "Input number : "; int number; cin >> number;
if (deque.isBelong(number))
{
cout << number << " belongs.\n";
}
else
{
cout << number << " does not belong.\n";
}
system("pause");
system("cls");
break;
case 12:
cout << "Deque before reverse: "; deque.show(); cout << endl;
cout << "Deque after reverse: "; deque.reverse(); deque.show(); cout << endl;
system("pause");
system("cls");
break;
default:
cout << "There is no " << choice << " choice!" << endl;
system("pause");
system("cls");
break;
}
}
}
However, reverse() method works inappropriate way.
Testing code I noticed that several methods working inappropriate way after reversing:
getRear() - returns old value;
deleteLast() - crashes.
Reverse() method based totally on same method in linked list implementation,as swap(), although it works with some problems.
I have not looked through all your code though I am sure it has some bugs as for example in the default constructor of the class Node
Node()
{
this->mData = mData;
pPrev = pNext = NULL;
}
where uninitialized data member mData is assigned to itself.
Or if you are using the operator new then you should use the operator delete instead of the standard C function free as you are doing
free(temp);
Or another example. Your method reverse does not change the pointer pRear. Or the data member pPrev also is not changed for the pointer curr.
Or the method swap has a memory leak.
And so on.
I will show how the method Reverse can be implemented.
In fact what you need is to swap data members pPrev and pNext for each node of the list.
Here is a demonstration program. I have made some changes for your classes to simplify the implementation of the demonstration program. For example I have made the class Node an internal class of the class Deque (you should also do that.). In any case you can use the idea that is realized in the method Reverse in your own implementation of the method.
#include <iostream>
#include <utility>
class Deque
{
private:
struct Node
{
int mData;
Node *pPrev, *pNext;
} *pFront = nullptr, *pRear = nullptr;
int mSize = 0;
public:
void Push( int data )
{
Node *newNode = new Node{ data, pRear, nullptr };
if (pFront == nullptr)
{
pFront = newNode;
}
else
{
pRear->pNext = newNode;
}
pRear = newNode;
++mSize;
}
Deque & Reverse()
{
if (pFront && pFront->pNext)
{
std::swap( pFront, pRear );
for (Node *current = pFront; current; current = current->pNext)
{
std::swap( current->pPrev, current->pNext );
}
}
return *this;
}
std::ostream &Show( std::ostream &os = std::cout ) const
{
os << mSize << ": ";
for (Node *current = pFront; current; current = current->pNext)
{
os << current->mData << " -> ";
}
return os << "null";
}
std::ostream &ShowReversed( std::ostream &os = std::cout ) const
{
os << mSize << ": ";
for (Node *current = pRear; current; current = current->pPrev)
{
os << current->mData << " -> ";
}
return os << "null";
}
};
int main( void )
{
Deque deque;
const int N = 10;
for (int i = 0; i < N; i++)
{
deque.Push( i );
}
deque.Show() << '\n';
deque.ShowReversed() << '\n';
std::cout << '\n';
deque.Reverse();
deque.Show() << '\n';
deque.ShowReversed() << '\n';
std::cout << '\n';
}
The program output is
10: 0 -> 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> null
10: 9 -> 8 -> 7 -> 6 -> 5 -> 4 -> 3 -> 2 -> 1 -> 0 -> null
10: 9 -> 8 -> 7 -> 6 -> 5 -> 4 -> 3 -> 2 -> 1 -> 0 -> null
10: 0 -> 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> null

I want to make a program where an input from the user is separated into 3 circular linked lists. But I am facing return value 3221225725 error

A Bank manager want to segregate different Currency notes in to 3 different baskets. Initially, all the currencies are in one Basket and the currencies are USD, INR and EUR. Now, you are supposed to write a program that can segregate the currencies to 3 different buckets. While, segregation, make sure to have a track of the overall sum of the currencies in terms of INR for each basket.
Program Requirements:
1.First get the input from the user for the overall Basket. [Even numbers are mapped as USD, Odd numbers are mapped as INR and Prime numbers are mapped as EUR, if there is an intersection, you are free to select any one of them]
2.After receiving the elements of the Basket, try a function to segregate the currencies
3.While adding the currency to its corresponding basket, ensure to calculate the overall sum.
4.Whenever, the bank manager wants to see the basket, you should display all the baskets and its corresponding SUM, MEAN, MEDIAN and MODE.
5.Also, there should be a provision to remove required amount of currency in each basket. [While removal, you need to enter the amount of removal in INR and its corresponding value should be removed from the respective basket]
NOTE: Use the value, USD = 73 INR and EUR = 86.5 INR
#include<iostream>
#include<cstdio>
#include<cstdlib>
using namespace std;
int prime(int n);
struct node
{
int info;
struct node *next;
}*last;
class circular_llist
{
public:
void insert(int value);
void delete_element(int value);
void display_list();
circular_llist()
{
last = NULL;
}
};
int main()
{
int element, choice, ch;
int arr[100], i, n, x;
int sum_usd=0, sum_inr=0, sum_eur=0;
int c_usd=0, c_inr=0, c_eur=0;
int arr_usd[n], arr_inr[n], arr_eur[n];
cout << "Enter the total number of elements" << endl;
cin >> n;
cout << "Enter the elements:" << endl;
for(i=0;i<n;i++) {
cin >> x;
arr[i]=x;
}
circular_llist usd;
circular_llist inr;
circular_llist eur;
for(i=0;i<n;i++) {
if(prime(arr[i])==1) {
eur.insert(arr[i]);
sum_eur+=arr[i];
c_eur++;
}
else if(arr[i]%2==0) {
usd.insert(arr[i]);
sum_usd+=arr[i];
c_usd++;
} else {
inr.insert(arr[i]);
sum_inr+=arr[i];
c_inr++;
}
}
do{
cout << "1.Delete Element" << endl;
cout << "2.Display elements" << endl;
cout << "3.Show mathematical figures" << endl;
cout << "4.Quit" << endl;
cin >> ch;
switch(ch)
{
case 1:
cout << "From which basket do you want to delete?" << endl;
cout << "1.USD" << endl << "2.INR" << endl << "3.EUR" << endl;
cin >> choice;
switch(choice)
{
case 1:
if (last == NULL)
{
cout<<"List is empty, nothing to delete"<<endl;
break;
}
cout<<"Enter the element for deletion: ";
cin>>element;
usd.delete_element(element);
cout<<endl;
break;
case 2:
if (last == NULL)
{
cout<<"List is empty, nothing to delete"<<endl;
break;
}
cout<<"Enter the element for deletion: ";
cin>>element;
inr.delete_element(element);
cout<<endl;
break;
case 3:
if (last == NULL)
{
cout<<"List is empty, nothing to delete"<<endl;
break;
}
cout<<"Enter the element for deletion: ";
cin>>element;
eur.delete_element(element);
cout<<endl;
break;
}
case 2:
cout << "From whick basket do you want to diplay thye elements?" << endl;
cout << "1.USD" << endl << "2.INR" << endl << "3.EUR" << endl;
cin >> choice;
switch(choice)
{
case 1:
usd.display_list();
cout << endl;
break;
case 2:
inr.display_list();
cout << endl;
break;
case 3:
eur.display_list();
cout << endl;
break;
}
case 3:
cout << "For which basket do you want tp show the mathematical figures?" << endl;
cout << "1.USD" << endl << "2.INR" << endl << "3.EUR" << endl;
cin >> choice;
switch(choice)
{
case 1:
cout << "Sum = " << sum_usd << endl;
cout << "Mean = " << endl;
case 2:
cout << "Sum = " << sum_inr << endl;
case 3:
cout << "Sum = " << sum_eur << endl;
}
case 4:
cout << "EXIT" << endl;
break;
default :
cout << "Choose a valid option" << endl;
break;
}
}while(ch!=4);
return 0;
}
/*
* Create Circular Link List
*/
void circular_llist::insert(int value)
{
struct node *temp;
temp = new(struct node);
temp->info = value;
if (last == NULL)
{
last = temp;
temp->next = last;
}
else
{
temp->next = last->next;
last->next = temp;
last = temp;
}
}
/*
* Deletion of element from the list
*/
void circular_llist::delete_element(int value)
{
struct node *temp, *s;
s = last->next;
/* If List has only one element*/
if (last->next == last && last->info == value)
{
temp = last;
last = NULL;
free(temp);
return;
}
if (s->info == value) /*First Element Deletion*/
{
temp = s;
last->next = s->next;
free(temp);
return;
}
while (s->next != last)
{
/*Deletion of Element in between*/
if (s->next->info == value)
{
temp = s->next;
s->next = temp->next;
free(temp);
cout<<"Element "<<value;
cout<<" deleted from the list"<<endl;
return;
}
s = s->next;
}
/*Deletion of last element*/
if (s->next->info == value)
{
temp = s->next;
s->next = last->next;
free(temp);
last = s;
return;
}
cout<<"Element "<<value<<" not found in the list"<<endl;
}
/*
* Display Circular Link List
*/
void circular_llist::display_list()
{
struct node *s;
if (last == NULL)
{
cout<<"List is empty, nothing to display"<<endl;
return;
}
s = last->next;
cout<<"Circular Link List: "<<endl;
while (s != last)
{
cout<<s->info<<"->";
s = s->next;
}
cout<<s->info<<endl;
}
/*
*Check in the element is prime or not
*/
int prime(int n) {
int i;
int a;
for(i=2;i<n;i++){
if(n%i==0) {
a = 0;
break;
}
}
return a;
}
Change this: int arr_usd[n], arr_inr[n], arr_eur[n];
Into this: int arr_usd[20], arr_inr[20], arr_eur[20];
or any other number other than 20. It shows an error as n value hasn't been initialised yet.
Done completely using LinkedList in C
#include <stdio.h>
#include <stdlib.h>
struct Node{
float data;
struct Node* next;
};
struct Node *EUR=NULL;
struct Node *USD=NULL;
struct Node *INR=NULL;
void sort(struct Node **h){
struct Node* node1;
struct Node* node2;
int temp;
for(node1=*h;node1!=NULL;node1=node1->next){
for(node2=node1->next;node2!=NULL;node2=node2->next){
if(node1->data>node2->data){
temp = node1->data;
node1->data = node2->data;
node2->data = temp;
}
}
}
}
void add(float val,struct Node **h){
struct Node *temp = (struct Node*)malloc(sizeof(struct Node));
temp->data = val;
temp->next = NULL;
if(*h==NULL){
*h = temp;
return;
}
struct Node *node = *h;
while(node->next!=NULL){
node = node->next;
}
node->next = temp;
}
void delete(struct Node** h, float amt){
struct Node *node = *h;
if(*h!=NULL){
if(node->data==amt){
*h = node->next;
}else{
int flag=0;
while(node->next!=NULL){
if(node->next->data==amt){
node->next = node->next->next;
flag=1;
printf("[*]Amount removed\n");
break;
}
node = node->next;
}
if(!flag){
printf("[*]Amount not in Basket!!!\n");
}
}
}else{
printf("[*]Failed\tZero Balance\n");
}
}
float sum(struct Node** h){
if(*h==NULL)
return 0;
float s=0;
struct Node *node = *h;
while(node!=NULL){
s += node->data;
node = node->next;
}
return s;
}
float mean(struct Node** h){
if(*h==NULL)
return 0;
int l=0;
float m,s=0;
struct Node *node = *h;
while(node!=NULL){
l++;
s += node->data;
node = node->next;
}
m =s/l;
return m;
}
float median(struct Node** h){
if(*h==NULL)
return -1;
float med;
struct Node* f_node = *h;
struct Node* p_node = *h;
struct Node* s_node = *h;
while(f_node!=NULL && f_node->next!=NULL){
f_node = f_node->next->next;
p_node = s_node;
s_node = s_node->next;
}
if(f_node!=NULL){//odd
med = s_node->data;
}else{
med = (p_node->data+s_node->data)/2;
}
return med;
}
int mode(struct Node **h){
if(*h==NULL)
return 0;
int max_value=0;
int count,max_count = 0;
struct Node *node = *h;
while (node!=NULL){
count = 0;
struct Node *node2 = node->next;
while(node2!=NULL){
if(node->data==node2->data)
count++;
node2 = node2->next;
}
if(count>max_count){
max_value = node->data;
max_count = count;
}
node = node->next;
}
if(max_count==0)
return 0;
return max_value;
}
void print(struct Node** h,char *m){
printf("printing %s>>>\n",m);
if(*h==NULL){
printf("[*]No bills\n");
return;
}
struct Node* node = *h;
while(node->next!=NULL){
printf("%.2f->",node->data);
node = node->next;
}
printf("%.2f\n",node->data);
printf("[*]SUM: %.2f\n",sum(h));
printf("[*]MEAN: %.2f\n",mean(h));
printf("[*]MEDIAN: %.2f\n",median(h));
printf("[*]MODE: %d\n",mode(h));
}
int even(int n){
if(n%2==0)
return 1;
return 0;
}
int prime(int n){
for(int i=2;i<=n/2;i++){
if(n%i==0){
return 0;
}
}
return 1;
}
int main(){
int n;
int num;
printf("Enter total no of bills: ");
scanf("%d",&n);
float eur = 86.5f;
float usd = 73.0f;
for(int i=0;i<n;i++){
printf("Enter bill %d: ",i+1);
scanf("%d",&num);
if(prime(num))
add(eur*num,&EUR);
else if(even(num))
add(usd*num,&USD);
else
add((float)num,&INR);
}
sort(&EUR);
sort(&USD);
sort(&INR);
int ch1,ch2,br=0;
float amt;
while(1){
printf("1.Display Baskets\n2.Delete Amount\n3.Quit\nEnter your choice: ");
scanf("%d",&ch1);
switch(ch1){
case 1:
print(&EUR,"EURO");
print(&USD,"USD");
print(&INR,"INR");
break;
case 2:
printf("Enter amount to be deleted: ");
scanf("%f",&amt);
printf("Delete From>>>\n1.EUR\t2.USD\t3.INR");
scanf("%d",&ch2);
switch(ch2){
case 1:
delete(&EUR,amt);
break;
case 2:
delete(&USD,amt);
break;
case 3:
delete(&INR,amt);
break;
default:
printf("[*]Wrong Input\n");
break;
}
break;
default:
br = 1;
break;
}
if(br)
break;
}
}```

linked list insert and printing C++

So i am trying to use double pointers to create insert function and then print the linked list.
I managed to do it with single pointers but this double pointer is driving me insane.
#include <iostream>
#include <string>
using namespace std;
class Node {
public:
string name;
int ID;
int marks[10];
Node *next;
};
void printOptions() {
cout << endl;
cout << "1.Insert New Node" << endl;
cout << "2.Print List" << endl;
cout << "3.Exit" << endl;
}
void insertAtBack(string inputName, Node **headref) {
Node **currentNodeRef;
currentNodeRef = headref;
while ((*currentNodeRef)->next != NULL) {
(*currentNodeRef) = (*currentNodeRef)->next;
}
(*currentNodeRef)->next = new Node();
(*currentNodeRef)->next->name = inputName;
(*currentNodeRef)->next->next = NULL;
}
void printList(Node *head) {
Node *indexNode;
indexNode = head;
while (indexNode != NULL) {
cout << (indexNode)->name << endl;
(indexNode) = (indexNode)->next;
}
}
int main() {
cout << "This implements a linked list" << endl;
int option;
bool infinite = true;
Node *head = NULL;
string testName;
while (infinite == true) {
printOptions();
std::cin >> option;
switch (option) {
case 1:
cout << "Enter student name" << endl;
std::cin >> testName;
if (head == NULL) {
head = new Node();
head->name = testName;
}
else {
insertAtBack(testName, &head);
}
break;
case 2:
printList(head);
break;
case 3:
exit(1);
break;
default:
exit(1);
break;
}
}
return 0;
}
So there is no compilation error or seg fault but instead the code runs it takes in 2 values and prints them fine. when the another value is typed inserted it only prints 2 values no more.
I think the print function is good because it worked previously with single pointer but i am not 100% sure.
I think the problem is in the insert function but i am not sire where.
void insertAtBack(string inputName, Node **headref) {
Node **currentNodeRef;
currentNodeRef = headref;
...
Node **currentNodeRef = headref; is an error. Remember you are passing the address of a pointer. You mean to write:
Node *currentNodeRef = *headref;
And change the function like so:
void insertAtBack(string inputName, Node **head)
{
Node *tail = *head;
while(tail->next != NULL)
tail = tail->next;
tail->next = new Node();
tail->next->name = inputName;
tail->next->next = NULL;
}
Also don't forget to initialize head->next = nullptr;
if (head == NULL) {
head = new Node();
head->name = testName;
head->next = nullptr; <--- add
}
It is better however if insertAtBack is prepared to handle head when head is NULL. The whole reason you pass Node **head is because you want a reference to the pointer so you can initialize it. So you can modify the code as:
void insertAtBack(string inputName, Node **head)
{
Node *new_node = new Node();
new_node->name = inputName;
new_node->next = nullptr;
if(*head)
{
Node *tail = *head;
while(tail->next)
tail = tail->next;
tail->next = new_node;
}
else
{
*head = new_node;
}
}
void printList(Node *head)
{
Node *node = head;
while(node)
{
cout << node->name << endl;
node = node->next;
}
}
int main()
{
cout << "This implements a linked list" << endl;
Node *head = NULL;
string testName;
while(true)
{
printOptions();
int option;
std::cin >> option;
switch(option)
{
case 1:
cout << "Enter student name" << endl;
std::cin >> testName;
insertAtBack(testName, &head);
break;
case 2: printList(head); break;
case 3: exit(1); break;
default: exit(1); break;
}
}
return 0;
}

Run time error when I try printing the linked list

This is my code:
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
struct node
{
string program;
node *next;
}
bool isEmpty(node *head)
{
if (head == NULL)
return true;
else
return false;
}
void insertAsFirstElement(node *&head, node *&tail, string program)
{
node *temp = new node;
temp->program = program;
temp->next = NULL;
head = temp;
tail = temp;
}
void initialize(node *&head, node *&tail, string program)
{
if (isEmpty(head))
insertAsFirstElement(head, tail, program);
else
{
node* temp = new node;
temp->program = program;
temp->next = NULL;
tail->next = temp;
tail = temp;
}
}
void insert(node *& head, node *& tail, string program, int num)
{
if (isEmpty(head))
insertAsFirstElement(head, tail, program);
else
{
string free ("FREE");
int i = 0;
while (head != NULL)
{
while (head->program.compare(free) != 0)
head = head->next;
while (head->program.compare(free) == 0)
{
head->program = program;
tail->next = head;
tail = head;
i++;
if (i == (num-1))
return;
}
}
}
}
void showList(node *current)
{
if (isEmpty(current))
cout << "The list is empty. \n";
else
{
int i = 0;
cout << "The list contains: \n";
while(current != NULL)
{
cout << current->program << " ";
if ((i + 1) % 8 == 0)
cout << "\n";
current = current->next;
i++;
}
}
}
int main()
{
cout << "Menu";
cout << "\n1. Add program\n";
cout << "2. Print Memory\n";
cout << "3. Exit\n";
node *head = NULL;
node *tail = NULL;
int choice;
string name;
int memory;
int numPages;
for (int i = 0; i <= 31; i++)
{
initialize(head, tail, "FREE");
}
showList(head);
do
{
cout << "choice - ";
cin >> choice;
switch (choice)
{
case 1:
cout << "Program name - ";
cin >> name;
cout << "Program size - ";
cin >> memory;
if (memory % 4 == 0)
numPages = memory / 4;
else if (memory % 4 != 0)
numPages = memory / 4 + 1;
insert(head, tail, name, numPages);
cout << "Program " << name << " added succesfully.\n";
case 2:
showList(head);
}
} while (choice!=3);
return 0;
}
The error is in the insert function because when I try printing the linked list after I call the insert function it never stops printing, but I don't understand my mistake.
Also in the switch in the main when insert 2 as choice it only runs case 2, but when I insert 1 as choice it runs both case 1 and case 2.
EDIT: I haven't changed anything and now once I call the insert function the program stops running
Regarding switch case, you need to add break; after case 1:
"The error is in the insert function"
So why do you not fix it?
I agree, that your insert function is flawed. Below I have marked 3 lines that probably contribute to the code's problems.
Key Idea: When inserting the second and subsequent items to a linked list, your code should modify only 'head' or 'tail', never both.
When inserting at the head, the tail should not change.
When inserting at the tail, the head should not change.
vv vv
void insert(node *& head, node *& tail, string program, int num)
{
if (isEmpty(head))
insertAsFirstElement(head, tail, program);
else
{
string free ("FREE");
int i = 0;
while (head != NULL)
{
while (head->program.compare(free) != 0)
head = head->next; <<<<<<<<<<<<<<<<<<<<<
while (head->program.compare(free) == 0)
{
head->program = program; <<<<<<<<<<<<<<<<<<<<
tail->next = head;
tail = head; <<<<<<<<<<<<<<<<<<<<
i++;
if (i == (num-1))
return;
}
}
}
}
Your switch statement is missing a break; statement. Since there is no break statement for case 1, the compiler continues through case 1 and 2, since case 2 follows case 1.
Here is a more clear description from Tutorialspoint:
When the variable being switched on is equal to a case, the statements following that case will execute until a break statement is reached.
When a break statement is reached, the switch terminates, and the flow of control jumps to the next line following the switch statement.
Not every case needs to contain a break. If no break appears, the flow of control will fall through to subsequent cases until a break is reached.
See this code:
switch (choice)
{
case 1:
// ... Add the rest of your code here
break // <-- this is required so that the switch is termintated after completing the appropriate case instead of continuing on to the next case
case 2:
showList(head); // there are no more cases after this, so only this case runs if switch(2) occurs.
}

Output of c++ program not coming as expected

I have made a C++ program for a binary tree. But the terminal is not asking the statement for inputting the direction for where the elements are to be placed.
Also when I replace the statement from " node *temp = new node " to "node *temp=NULL" the program stops working .
#include <iostream>
#include <cstring>
using namespace std;
class node {
int data;
node * left;
node * right;
public:
node * level_order(node * first);
node * create_bt(node * first);
void display(node * first);
};
//node *first=NULL;
node * node::create_bt(node * first) {
node * temp = new node;
int ele;
//char dir;
cout << "\n Enter data ";
cin >> ele;
temp->data = ele;
temp->left = NULL;
temp->right = NULL;
if (first == NULL) {
temp = first;
return first;
} else {
char dir[20];
cout << "\n Enter the direction ";
cin >> dir;
node * cur = first;
int j = 0;
while (dir[j] != '\0') {
if (dir[j] == 'l') {
cur = cur->left;
}
if (dir[j] == 'r') {
cur = cur->right;
}
j++;
}
cur = temp;
return first;
}
}
void node::display(node * first) {
if (first == NULL)
return;
cout << "\n " << first->data;
display(first->left);
display(first->right);
}
int main() {
int n;
node s;
node * first = NULL;
cout << "\n No of elements ";
cin >> n;
for (int i = 0; i < n; i++) {
first = s.create_bt(first);
}
s.display(first);
return 0;
}
first=s.create_bt(first); does not changes state, from NULL to 'l' or 'r'. You have to change that.
node*node::create_bt(node *first)
{
node *temp=new node;
int ele;
//char dir;
cout<<"\n Enter data ";
cin>>ele;
temp->data=ele;
temp->left=NULL;
temp->right=NULL;
char dir[20];
cout<<"\n Enter the direction ";
cin>>dir;
if(first==NULL)
{
temp=first;
return first;
}
else
{
node*cur=first;
int j=0;
while(dir[j]!='\0')
{
if(dir[j]=='l')
{
cur=cur->left;
}
if(dir[j]=='r')
{
cur=cur->right;
}
j++;
}
cur=temp;
return first;
}
}
I believe you re looking something like this. This is a basic binary tree, i had to make a basic one in order to understand how it works and how it chooses left and right. I make a class inside a class, in order to have access to my data members (node class, int data, *left , *right) and have them at the same time protected, all-in-one. As you can see "newnode" just creates a node and NULL s the pointers. Thats it. "Find" searches and finds a node with a current key, and returns it when exits. All the rest, i guess, you can understand them, as they are prety much the same with your code. The only thing you have to do is to define, when you want to direct the node you want. REMINDER: You have to find a way to utilize it, so the leafs will not end far-left or far-right.("Enter the direction"). I hope i helped you understand.
#include <iostream>
#include <conio.h>
using namespace std;
class mybTree {
class node {
public:
int data;
node * left;
node *right;
};
node *root;
node *newnode(int num){
node *newnode1;
newnode1 = new (nothrow) node;
newnode1->data = num;
newnode1->left = NULL;
newnode1->right = NULL;
return newnode1;
}
public:
node *find (int key) {
node *current;
current = root;
while (current->data !=key){
if (key<current->data){
current = current->left;
} else {
current = current->right;
}
if (current == NULL){
return NULL;
}
}
return NULL;
}
void display (node *ptr);
void display_tree();
bool insert(int num);
void post_order_delete(node *ptr);
mybTree();
~mybTree();
};
int main(){
char ch = ' ';
int a;
mybTree mybTree1;
while (ch !='0'){
cout << "0->Exit"<<endl<< "1-> add"<<endl<< "2-> find" <<endl<<"3-> Show me the tree\n";
ch = getch();
switch (ch) {
case '0':
break;
case '1':
cout << "number";
cin >> a;
if (!mybTree1.insert(a)){
cout << "Not enough memory" << endl;
}
break;
case '2' :
cout << "Number:" ;
cin >> a;
if (mybTree1.find(a)!=NULL) {
cout << "Found" << endl;
} else {
cout << "Not existed" << endl;
}
break;
case '3':
mybTree1.display_tree();
cout<<endl;
break;
default:
cout << "Wrong Message";
break;
}
}
return 0;
}
void mybTree::display(node *ptr) {
if (ptr == NULL){
return;
}
display(ptr->left);
cout << ptr->data<<endl;
display(ptr->right);
}
void mybTree::display_tree() {
//Displays the Tree
display(root);
}
bool mybTree::insert(int num) {
//It inserts a node. Desides left or right.
node *next,*current,*ptr;
int isleft;
next = current = root;
ptr = newnode(num);
if (ptr == NULL) {
return false;
}
if (root == NULL) {
root = ptr;
return true;
}
while (1){
if (num < current->data){
next = current->left;
isleft = 1;
} else {
next = current->right;
isleft = 0;
}
if (next == NULL){
if (isleft){
current->left = ptr;
} else {
current->right = ptr;
}
return true;
}
current=next;
}
return false;
}
void mybTree::post_order_delete(node *ptr) {
//deletes the node. Usefull for destructor
if (ptr == NULL){
return;
}
post_order_delete(ptr->left);
post_order_delete(ptr->right);
cout << ptr->data;
delete ptr;
}
mybTree::mybTree() {
//Constructor
root = NULL;
}
mybTree::~mybTree() {
//Destructor
post_order_delete(root);
root = NULL;
}