This is a FIFO program using linked list . The program does not give the desired output but generates a long loop which stops after sometime and there is a message that the program has stopped working. What is the problem ?
#include <iostream>
using namespace std;
struct node {
int data;
struct node* previous; // This pointer keeps track of the address of the previous node
};
struct queue {
node* first;
node* last;
};
node* dataNode_P_A;
bool loop = true;
struct node* enterData();
struct node* enter_N_Data();
void displayQueue();
int main() {
struct node* dataNode= enterData();
while( loop ) {
cout << "Want to enqueue ? Press y/n : ";
char ans;
cin >> ans;
if( ans == 'y' ) {
struct node* dataNode_N = enter_N_Data();
} else {
break;
}
}
displayQueue();
}
struct node* enterData() {
cout << "Enter the number : ";
dataNode_P_A = new node; // Now dataNode points to a chunk allocated to node
cin >> dataNode_P_A->data;
dataNode_P_A->previous = NULL; // this is set to NULL because no one follows till now
queue* q = new queue;
q->first = dataNode_P_A; // this pointer points to the first element
return dataNode_P_A;
}
struct node* enter_N_Data() {
cout << endl << "Enter the number : ";
node* dataNode = new node;
cin >> dataNode->data;
dataNode->previous = dataNode_P_A;
queue* q = new queue;
q->last = dataNode; // this pointer points to the last element
return dataNode;
}
void displayQueue() {
while( dataNode_P_A != NULL ) {
cout << dataNode_P_A->data << endl;
dataNode_P_A++;
}
}
You are constructing queues and then abandoning them.
You fail to update dataNode_P_A, so that you are not constructing a list so much as a tassel.
You invoke dataNode_P_A++ when you clearly don't know what it means.
You have written a long, complicated piece of code without testing it along the way.
You should start over, and go step by step.
Where to begin... First off the queue data structure isn't particularly used for anything. But that's not the root of your problem. That lies here:
void displayQueue() {
while( dataNode_P_A != NULL ) {
cout << dataNode_P_A->data << endl;
dataNode_P_A++;
}
}
When iterating through a linked list, you move to the next element by navigating to ->previous:
void displayQueue() {
while( dataNode_P_A != NULL ) {
cout << dataNode_P_A->data << endl;
dataNode_P_A = dataNode_P_A->previous;
}
}
Having said that, you're doing some other things that are questionable - like modifying your global list (dataNode_P_A). That's not a problem in your example, but it can be a problem if you ever want to do anything to the list other than display it.
Here's another version of displayQueue that doesn't have that problem:
void displayQueue() {
node *entry = dataNode_P_A;
while( entry != NULL ) {
cout << entry->data << endl;
entry = entry->previous;
}
}
You should edit your enter_N_Data() function like:
node* temp; // global as others in your program
struct node* enter_N_Data() {
cout << endl << "Enter the number : ";
node* dataNode = new node;
cin >> dataNode->data;
temp = new node;
temp = dataNode_P_A;
dataNode_P_A = dataNode; // update dataNode_P_A
dataNode->previous = temp;
queue* q = new queue;
q->last = dataNode; // this pointer points to the last element
return dataNode;
}
and keep everything same while following the suggestions by # Larry Osterman and # Beta.
Related
I'm working on an assignment for my college class, and I'm struggling to figure out why code for my push_front() function works without fail, but my push_back() always gives:
"Exception thrown: read access violation. st was nullptr."
struct NodeDate
{
int day, month, year; //Structure's data
struct NodeDate* nextNode; //Pointer to point to next node
}*start; //Not sure why we do this, but all examples contain it
class LinkedListDate
{
public:
//Prototype of member functions
NodeDate* create_node(NodeDate);
void push_front();
void pop_front();
void remove_front();
void search();
void display();
LinkedListDate();
void push_back();
void remove_back();
void pop_back();
};
LinkedListDate::LinkedListDate()
{
start = NULL; //Our first created pointer will be set to NULL
}
NodeDate* LinkedListDate::create_node(struct NodeDate newDate) //Function that creates a new node and returns said node
{
struct NodeDate* tempNode, *s;
tempNode = new(struct NodeDate); //Reserving memory for our temp node
if (tempNode == NULL) //If the node is empty
{
std::cout << "Memory not allocated " << std::endl;
return 0;
}
else //Otherwise assign parameter node value to temporary node
{
tempNode->day = newDate.day;
tempNode->month = newDate.month;
tempNode->year = newDate.year;
tempNode->nextNode = NULL; //Remember these are all values contained within the date struct
return tempNode; //Return the node
}
}
void LinkedListDate::push_front() //Function that will insert a node at the start of our linkedlist
{
struct NodeDate* tempNode, *st, newNode;
std::cout << "Enter the day: ";
std::cin >> newNode.day;
std::cout << "Enter the month: ";
std::cin >> newNode.month;
std::cout << "Enter the year: ";
std::cin >> newNode.year;
tempNode = create_node(newNode); //Creating a new node for date with the create_node function
if (start == NULL) //Checks if the starting (Head) node is NULL then first node to insert
{
start = tempNode; //Start node points to our temporary node
start->nextNode = NULL; //Assign null to start->next
}
else //Otherwise nodes are already available in the list
{
st = start; //Assign start to st
start = tempNode; //Start points to temporary node
start->nextNode = st; //Start next point to st
}
std::cout << "Element Inserted at beginning" << std::endl;
}
void LinkedListDate::push_back() //Function to insert a new node at the end of the linkedlist
{
struct NodeDate* tempNode, *st, newNode;
std::cout << "Enter the day: ";
std::cin >> newNode.day;
std::cout << "Enter the month: ";
std::cin >> newNode.month;
std::cout << "Enter the year: ";
std::cin >> newNode.year;
tempNode = create_node(newNode); //Creating a new node for date with the create_node function
st = start;
while (st->nextNode != NULL) //Move til we reach end of the list
{
st = st->nextNode; //Move to the next node
}
tempNode->nextNode = NULL; //Assign null to temporary node next
st->nextNode = tempNode; //st next points to temporary node
std::cout << "Element Inserted at last" << std::endl;
}
Again, push_front() works, but push_back() does not work (The program runs, but after inputting the date for the first node I get the exception.
I've been trying a lot of things, but I can't seem to figure out what exactly I'm doing wrong.
struct NodeDate
{
//...
}*start;
is the same is
struct NodeDate
{
//...
};
NodeDate *start;
push_back will fail when the list is empty (i.e. start is null).
void LinkedListDate::push_back()
{
//...
tempNode = create_node(newNode);
tempNode->nextNode = nullptr;
if(start == nullptr)
{
start = tempNode;
}
else
{
st = start;
while (st->nextNode != nullptr) //Move til we reach end of the list
{
st = st->nextNode; //Move to the next node
}
st->nextNode = tempNode;
}
std::cout << "Element Inserted at last" << std::endl;
}
I'm a beginner programmer in my first years in college, I'm working with single linked lists in c++, and I'm trying to write a program without using classes
to create a single linked list input from a user and print it, then I want to put the even numbers
in a new list and print this new list and the odd numbers in another new list and
print it too.
I began with this, I wish if someone can help me.
#include <iostream>
using namespace std;
struct node {
int data;
node* next;
};
struct Even_node {
int even_data;
Even_node* even_next;
};
void creat(node*& head, node*& tail)
{
int num;
cout << "enter number , (0) to quiet\n";
cin >> num;
while (num != 0) {
node* nptr = new node;
nptr->data = num;
if (head == nullptr)
head = nptr;
else
tail->next = nptr;
tail = nptr;
tail->next = nullptr;
cout << "enter number again or 0 to quiet\n";
cin >> num;
}
}
void print(node* head)
{
cout << "the list is:\t";
while (head != nullptr) {
cout << head->data << "\t";
head = head->next;
}
cout << endl;
}
main()
{
node *head = nullptr, *tail = nullptr;
creat(head, tail);
print(head);
}
First I fixed the problems
removed dynamic memory allocations and memory leaks
it's int main https://en.cppreference.com/w/cpp/language/main_function
#include <iostream>
#include <memory>
using std::cout;
using std::cin;
struct node {
int data;
std::unique_ptr<node> next;
};
struct list {
std::unique_ptr<node> head;
node *tail;
};
void creat(list &l)
{
int num;
cout << "enter number , (0) to quiet\n";
cin >> num;
while (num != 0) {
std::unique_ptr<node> nptr = std::make_unique<node>();
nptr->data = num;
if (!l.head) {
l.head = std::move(nptr);
l.tail = l.head.get();
} else {
l.tail->next = std::move(nptr);
l.tail = l.tail->next.get();
}
cout << "enter number again or 0 to quiet\n";
cin >> num;
}
}
void print(const list &l)
{
auto node = l.head.get();
cout << "the list is:\t";
while (node != nullptr) {
cout << node->data << "\t";
node = node->next.get();
}
cout << '\n';
}
int main()
{
list l;
creat(l);
print(l);
}
Now you can create a second list, call it even, iterate through the first list and copy all even elements into the second list.
I tried implementing Linked List using C++ using a structure.
I've included three functions - Size, Insertion and Deletion from the end.
The program compiled successfully. During execution, when I tried to give input for the LLInsert() function, there was just a cursor blinking on my execution window. I don't know if the function returned to main.
Also the LLSize() doesn't return 0 when I try to find the Size of a empty list.
I can't seem to figure out what I'm doing wrong. Here is my code.
#include<iostream>
using namespace std;
struct LL {
LL *next = NULL;
int data;
};
int LLSize(LL *head) {
LL *current = new LL;
current = head;
int count = 0;
while(current != NULL) {
current = current -> next;
count ++;
}
return count;
}
void LLInsert(LL *head,int value) {
LL *current = new LL;
current = head;
LL *Newnode = new LL;
Newnode -> data = value;
Newnode -> next = NULL;
if(head == NULL) {
head = Newnode;
return;
}
while(current->next != NULL) {
current = current->next;
}
current->next = Newnode;
return;
}
int LLDelete(LL *head) {
LL *current = new LL;
current = head;
int deleteddata;
while(current->next->next != NULL) {
current = current->next;
}
current->next->data = deleteddata;
current->next = NULL;
return deleteddata;
}
int main() {
int choice;
LL *A;
while(1) {
cout << "1. Size\n2. Insert\n3. Delete\n4. Exit" << endl;
cout << "Enter a choice : ";
cin >> choice;
switch(choice) {
case 1 : {
cout << "\nLength = " << LLSize(A) << endl;
break;
}
case 2 : {
int value;
cout << "\nEnter the element to insert : ";
cin >> value;
LLInsert(A,value);
break;
}
case 3 : {
cout << LLDelete(A);
break;
}
case 4 : {
exit(0);
}
default : {
cout << "\nInvalid choice. Enter a valid choice " << endl;
break;
}
}
}
}
Don't use using namespace.
Create a type for the list and a type for the nodes
struct LL {
LL* next;
int data;
};
struct L {
LL* head;
};
Use references and don't allocate new memory in each function
int LLSize(L& list) {
LL *current = list.head;
Check if the head of the list is set and use nullptr
if (list.head == nullptr) {
Use an instance of the list and not a pointer
int main() {
int choice;
L A;
Use a debugger like gdb to analyze your program.
Clean up at the end. Delete memory you allocated with new. One delete for each new.
I have the following code but it gives an error on the line - e = list.first();(towards the end of the code). It says that it cannot convert Node to char can someone tell me how to get return the first value from the linked list in the variable e.
Thanks for all the help:)
//
// main.cpp
// cprogram1
//
#include <iostream>
using namespace std;
class Node {
char data;
Node* next;
public:
Node() {};
void SetData(int aData) { data = aData; };
void SetNext(Node* aNext) { next = aNext; };
char Data() { return data; };
Node* Next() { return next; };
};
// List class
class List {
Node *head;
public:
List() { head = NULL; };
void Print();
void Append(int data);
void Delete(int data);
Node * First() const;
};
/**
* Print the contents of the list
*/
void List::Print() {
// Temp pointer
Node *tmp = head;
// No nodes
if ( tmp == NULL ) {
cout << "EMPTY" << endl;
return;
}
// One node in the list
if ( tmp->Next() == NULL ) {
cout << tmp->Data();
cout << " --> ";
cout << "NULL" << endl;
}
else {
// Parse and print the list
do {
cout << tmp->Data();
cout << " --> ";
tmp = tmp->Next();
}
while ( tmp != NULL );
cout << "NULL" << endl;
}
}
/**
* Append a node to the linked list
*/
void List::Append(int data) {
// Create a new node
Node* newNode = new Node();
newNode->SetData(data);
newNode->SetNext(NULL);
// Create a temp pointer
Node *tmp = head;
if ( tmp != NULL ) {
// Nodes already present in the list
// Parse to end of list
while ( tmp->Next() != NULL ) {
tmp = tmp->Next();
}
// Point the last node to the new node
tmp->SetNext(newNode);
}
else {
// First node in the list
head = newNode;
}
}
/**
* Delete a node from the list
*/
void List::Delete(int data) {
// Create a temp pointer
Node *tmp = head;
// No nodes
if ( tmp == NULL )
return;
// Last node of the list
if ( tmp->Next() == NULL ) {
delete tmp;
head = NULL;
}
else {
// Parse thru the nodes
Node *prev;
do {
if ( tmp->Data() == data ) break;
prev = tmp;
tmp = tmp->Next();
} while ( tmp != NULL );
// Adjust the pointers
prev->SetNext(tmp->Next());
// Delete the current node
delete tmp;
}
}
Node * List::First() const {
Node *tmp = head;
return head;
}
int main ()
{
char c;
int t = 0;
char e;
List list;
while(t==0)
{
cout << "Please enter your command";
cin >> c;
if(c=='c')
{
cout << "You will need to enter 6 letters, one after the other";
cout << "Please enter the first letter";
cin >> e;
list.Append(e);
cout << "Please enter the second letter";
cin >> e;
list.Append(e);
cout << "Please enter the third letter";
cin >> e;
list.Append(e);
cout << "Please enter the fourth letter";
cin >> e;
list.Append(e);
cout << "Please enter the fifth letter";
cin >> e;
list.Append(e);
cout << "Please enter the sixth letter";
cin >> e;
list.Append(e);
list.Print();
list.Delete('b');
list.Print();
e = list.First();
}
}
}
Lets take a look to your program : tested here :
#include <iostream>
using namespace std;
class Node {
char data;
Node* next;
public:
Node() {};
void SetData(int aData) { data = aData; };
void SetNext(Node* aNext) { next = aNext; };
char Data() { return data; };
Node* Next() { return next; };
};
// List class
class List {
Node *head;
public:
List() { head = NULL; };
void Print();
void Append(int data);
void Delete(int data);
Node * First() const;
};
/**
* Print the contents of the list
*/
void List::Print() {
// Temp pointer
Node *tmp = head;
// No nodes
if ( tmp == NULL ) {
cout << "EMPTY" << endl;
return;
}
// One node in the list
if ( tmp->Next() == NULL ) {
cout << tmp->Data();
cout << " --> ";
cout << "NULL" << endl;
}
else {
// Parse and print the list
do {
cout << tmp->Data();
cout << " --> ";
tmp = tmp->Next();
}
while ( tmp != NULL );
cout << "NULL" << endl;
}
}
/**
* Append a node to the linked list
*/
void List::Append(int data) {
// Create a new node
Node* newNode = new Node();
newNode->SetData(data);
newNode->SetNext(NULL);
// Create a temp pointer
Node *tmp = head;
if ( tmp != NULL ) {
// Nodes already present in the list
// Parse to end of list
while ( tmp->Next() != NULL ) {
tmp = tmp->Next();
}
// Point the last node to the new node
tmp->SetNext(newNode);
}
else {
// First node in the list
head = newNode;
}
}
/**
* Delete a node from the list
*/
void List::Delete(int data) {
// Create a temp pointer
Node *tmp = head;
// No nodes
if ( tmp == NULL )
return;
// Last node of the list
if ( tmp->Next() == NULL ) {
delete tmp;
head = NULL;
}
else {
// Parse thru the nodes
Node *prev;
do {
if ( tmp->Data() == data ) break;
prev = tmp;
tmp = tmp->Next();
} while ( tmp != NULL );
// Adjust the pointers
prev->SetNext(tmp->Next());
// Delete the current node
delete tmp;
}
}
Node * List::First() const {
Node *tmp = head;
return head;
}
int main ()
{
char c;
int t = 0;
char e;
List list;
while(t==0)
{
cout << "Please enter your command";
c = 'c';
//cin >> c;
if(c=='c')
{
cout << "You will need to enter 6 letters, one after the other";
cout << "Please enter the first letter";
list.Append('e');
cout << "Please enter the second letter";
//cin >> e;
list.Append('a');
cout << "Please enter the third letter";
//cin >> e;
list.Append('b');
cout << "Please enter the fourth letter";
//cin >> e;
list.Append('f');
cout << "Please enter the fifth letter";
//cin >> e;
list.Append('h');
cout << "Please enter the sixth letter";
//cin >> e;
list.Append(e);
list.Print();
list.Delete('b');
list.Print();
e = list.First()->Data();
t=1;
}
}
}
As you can see, e = list.First() return a pointer to a Node, not a char. You have implemented a function that return a char which is Data(). Thus, you should use e = list.First()->Data();.
Also, your loop is infinite because t is always 0. I just put t=1 to stop your loop and see the result. (if you use this code, don't forget to uncomment the cin and remove c = 'c')
Hope that helps you.
When I run your code I get the error:
main.cpp: error: assigning to 'char' from incompatible type 'Node *'
e = list.First();
^ ~~~~~~~~~~~~
which I think explains it.
Try this:
e = list.First()->Data();
#include <iostream>
using namespace std;
struct Node
{
int item; // storage for the node's item
Node* next; // pointer to the next node
};
/**************
use reference
**************/
void addNode(Node*& head, int data , int& count)
{
Node * q; // new node
q = new Node; // allocate memory for the new mode
q->item = data; // inserting data for the new node
q->next = head; // point to previous node ?? how would i do that? ( am i doing it correctly?)
count++; // keep track of number of node
head = q;
}
int main()
{
int a, count = 0;
int data;
char callen;
Node *head = NULL;
do
{
cout << "please enter the data for the next node" << endl;
cin >> data;
addNode(head, data, count);
cout << "do you wish to enter another node? (enter true or false)" << endl;
cin >> callen;
}while( callen != 'n' );
// assuming this is the print function
while(head != NULL)
{
cout << "output" << head->item << endl;
head = head->next; //next element
}
system("pause");
return 0;
}
I tried adding a new element in the list how would i move the head around like a LIFO memory (stack) so the last element is on the very top..
Any help would be appreciated ! The pointers and the nodes are messing with my brain lately ....
In the do-while loop try this
addNode(data, count, head);
instead of
addNode( data, count );
Also, change the signature of addNode as follows:
void addNode( int data , int& count , Node*& head)
The code shouldn't compile because you are using the variable head in addNode but head is local to main.
You could use std::stack for LIFO.
int main()
{
int a, count=0;
int data;
bool repeat;
stl::stack<int> lifo;
// assuming it is an empty list at the beginning and crating a new node below
cout << "enter some data" << endl;
cin >> a ;
lifo.push(a);
do
{
cout << "please enter the data for the next node" <<endl;
cin >> data;
lifo.push(data);
cout << "do you wish to enter another node? (enter true or false)" << endl;
cin >> repeat;
}
while (repeat == true);
// assuming this is the print function
while(!lifo.empty()) {
cout << lifo.pop() << endl;
}
system("pause");
return 0;
}
Sounds like you're trying to learn a bit about link lists. Awesome!
Anyway, I'm not going to give you the exact answer, but I'll give you some pointers in pseudo code, in particular for your addNode member function:
Node* addNode(Node* head, int data, int& count)
{
create a new node
let it point to head
return the pointer to the new node for it to become the new head node
}
int main()
{
// code...
head = addNode(head, data, count);
// more code...
}
As a visual:
head
\/
node A->node B->node C
new node->?
new node
\/
node A->node B->node C
The way you're doing it, by implementing your addNode function as a push operation, already moves the head around, so the head will always point to the last element you added.
Therefore, to implement a function to delete the last element added, you just need to write a simple pop operation: copy the address of the head, make the second element the new head, and release the memory at the copied address:
Node* oldHead = head;
head = head->next;
delete oldHead;
return head;
You could try the following modified code.
#include <iostream>
using namespace std;
struct Node
{
int item; // storage for the node's item
Node* next; // pointer to the next node
};
/**************
use reference
**************/
void addNode(Node*& head, int data , int& count)
{
Node * q; // new node
q = new Node; // allocate memory for the new mode
q->item = data; // inserting data for the new node
q->next = head; // point to previous node ?? how would i do that? ( am i doing it correctly?)
count++; // keep track of number of node
head = q;
}
int main()
{
int a, count = 0;
int data;
bool repeat;
Node *head = NULL;
// assuming it is an empty list at the beginning and crating a new node below
Node *temp;
temp = new Node ;
cout << "enter some data" << endl;
cin >> a ;
temp->item = a;
temp->next = head;
head = temp;
//^^ assuming thats creating the first node ^^
do
{
cout << "please enter the data for the next node" << endl;
cin >> data;
addNode(head, data, count);
cout << "do you wish to enter another node? (enter true or false)" << endl;
cin >> repeat;
}
while (repeat == true);
// assuming this is the print function
temp = head;
while(temp != NULL)
{
cout << "output" << temp->item << endl;
temp = temp->next; //next element
}
return 0;
}