I am trying to print the index of a multi linked list. Each node has two elements- a warehouse number and a tool number. I am printing all the tools in each warehouse. I am having a problem with iterating correctly through the list.
I am not getting the correct values and am having trouble finding the problem in my method.
struct Node
{
int WarehouseNumber;
int ToolNumber;
struct Node *n;
}
void showWarehouses()
{
int tempvalue;
bool flag = false;
struct Node *s;
s = start;
if (start == NULL)
{
cout<<"Unable";
return;
}
s->WarehouseN = tempvalue;
cout<<"Warehouse "<<tempvalue<< ": Tool ";
while(s != NULL)
{
if (s->WarehouseN == tempvalue)
{
flag = true;
cout<< s->ToolN <<" ";
s = s->next;
}
}
}
You haven't assigned any values to tempvalue so it causes undefined behavior. Read this post.
Also based on what you have in struct Node and your code, I think you can have something like this picture in the program and you want to print them.
So to top it off I would write something like this code:
void showWarehouses()
{
int tempvalue=1;
bool flag, cont;
struct Node *s;
if (start == NULL)
{
cout << "Unable";
return;
}
cont = true;
while (cont)
{
cont = false, flag = false;
s = start;
while (s)
{
if (s->WarehouseN == tempvalue){
cont = true;
if (!flag){
cout << "Warehouse " << tempvalue << ": Tool ";
flag = true;
}
cout << s->ToolN << " ";
}
s = s->next;
}
cout << endl;
tempvalue++;
}
}
If this:
s = start;
struct Node *s;
compiles, you have an s in a wider scope that just got set to start before being hidden inside showWarehouses by another variable named s. That would be a bad thing.
Anyway, The immediate result is showWarehouses's s is never initialized and it's probably dumb unluck that the program doesn't crash. Since s is not initialized, the rest of the program is printing garbage so the output being wrong is to be expected.
i am assuming that ->warehouseN and ->toolN get the warehouse and tool nums accordingly. This is for right after your if statement.
struct Node *temp;
while (s != NULL){
temp = s;
cout << "Warehouse " << s->warehouseN << ": Tool ";
while (s!= NULL) {
cout << s->toolN << " ";
s = s-> next;
}
s = temp->next;
cout << endl;
}
also, you should probably initiate s before setting it as start
Related
I am trying to get input of a queue with the linked list implementation. The issue is that the contents of the queue aren't being printed. I tried debugging but it says that in the function displayCar that pointer p is null regardless. I can't tell what's wrong with why pointer p is NULL. Is there a missing reference when I am trying to push from the carInput function?
#include <iostream>
#include <queue>
using namespace std;
class record
{
public:
string ownerID, plateNumber;
record* next;
};
void push(string ownerID1, string plateNumber1, record **head, record **tail) {
record *n = new record();
n->ownerID = ownerID1;
n->plateNumber = plateNumber1;
n->next = NULL;
if (*head == NULL) {
*head =*tail= n;
}
else {
(*tail)->next = n;
*tail = n;
}
}
void pop(record** head, record** tail) {
record* p = *head;
while (*head != NULL) {
*head = (*head)->next;
free(p);
p = *head;
}
if (*head == NULL)
{
*tail = NULL;
}
}
void carInput(record *head, record *tail) {
char choice = 'Y';
string ownTemp, plateTemp;
while (choice == 'Y') {
cout << "Enter Owner Name: ";
cin >> ownTemp;
cout << "Enter Plate Number: ";
cin >> plateTemp;
push(ownTemp,plateTemp,&head,&tail);
cout << "Press [Y] for next input: ";
cin >> choice;
}
}
void displayCar(record* head, record *tail) {
record* p = head;
cout << "List Of Cars: \n";
int i = 1;
while (p!= NULL) {
cout << i << ". Owner Name: " << p->ownerID << endl;
cout << i << ". Plate Number: " << p->plateNumber<< endl;
pop(&head,&tail);
i++;
}
}
void serviceCar(record *head,record*tail) {
record* p = head;
string plateTemp;
int i = 0, time = 0;
char choice = 'Y';
cout << "Enter Plate Number:";
cin >> plateTemp;
while (p!= NULL) {
if (p->plateNumber == plateTemp) {
cout << "There is [" << i << "] car in queue before your turn. Estimated time in queue: " << time;
}
else {
i++;
time = time + 45;
}
pop(&head,&tail);
}
}
int main() {
record* head = NULL;
record*tail = NULL;
cout << ":: Car Record::\n\n";
carInput(head,tail);
displayCar(head,tail);
serviceCar(head, tail);
}
I don't know why you are punishing yourself with code like this when you are in C++ and there are plenty easier ways to do the same, but I'll try to help anyway by underlining the main problems:
1). The main reason that you must be struggling is that in the first push, even after *head =*tail= n;, the *head->next is still NULL and later when you'll try to iterate from the head, as you do in pop, *head = (*head)->next; you will get nothing.
2). if you want to do pop, you should delete one element for each call, not the whole collection - so you need if instead of while.
You have while where you using pop for each iteration and in the pop you also have the while, so think about it.
Also, you should be returning the value to display it easily - or change the way you trying to cout p in displayCar.
3). When you want to display the collection you just have to iterate through the collection instead of deleting all the elements, which will leave you empty collection after one display. You just need to iterate and display them, not to delete, something like that:
record* p = *head;
int i = 0;
while (p != NULL) {
cout << i << ". Owner Name: " << p->ownerID << endl;
cout << i << ". Plate Number: " << p->plateNumber<< endl;
p = p->next;
i++;
}
There are some other points that should be mentioned, but I think that's enough to get the code right direction - anyway, my advice would be to try to take a good look for simple linked-list how it's done and then try Queue linked-list, or just check already written examples and then try it by yourself. GeeksForGeeks
Your carInput receives pointers by value, and modifying those pointers has no effect on the pointers you pass to it.
Thus, main's head and tail are always null.
(You solved this with the pushing and popping functions, but failed to apply the same principle here.)
void carInput(record **head, record **tail) {
char choice = 'Y';
string owner, plate;
while (choice == 'Y') {
cout << "Enter Owner Name: ";
cin >> owner;
cout << "Enter Plate Number: ";
cin >> plate;
push(owner, plate, head, tail);
cout << "Press [Y] for next input: ";
cin >> choice;
}
}
You need to combine this fix with the fixes pointed out in the comments.
I'm taking a class in c++ and one of our assignments is to make an ADT for a linked list and do the implementations.
I've done well so far. But now I'm supposed to add the elements in order.
The code below is my ADD-function and what i've accomplished with this code is to sort them GIVEN that there are only 2 elements in the list. (I'm working with the problem from the basics, and refine my code after).
The while-loop on line 11 is my attempt to iterate (and int t are for debugging)
The problem i have is that my program crash without error (cmd stops working) if i try to add a number greater than 5.
The strange thing here is that if i remove my while-loop, it works. I can't find out whats wrong. So i hope for a little help
Main.cpp:
int main() {
SortedDoublyLinkedList<int> *list = new SortedDoublyLinkedList<int>(5, nullptr, nullptr);
int counter = 0;
while (counter < 2) {
int add;
cout << "Enter number: ";
cin >> add;
list->add(add);
counter++;
cout << counter << endl;
}
cout << list->removeLast()->getData()<< endl;
cout << list->removeLast()->getData()<< endl;
cout << list->removeLast()->getData()<< endl;
return 0;
}
SortedDoublyLinkedList.cpp
template<class T>
DoublyLinkedNode<T> *SortedDoublyLinkedList<T>::add(T val) {
if (isEmpty()) {
head = new DoublyLinkedNode<T>(val);
head->setPrevious(nullptr);
head->setNext(nullptr);
} else {
DoublyLinkedNode<T> *newEl = new DoublyLinkedNode<T>(val);
DoublyLinkedNode<T> *temp = head;
int t = 0;
while(temp->getData() != nullptr){
temp = temp->getNext();
t++;
cout << t << endl;
}
if(newEl->getData() > head->getData()){
newEl->setPrevious(head);
newEl->setNext(nullptr);
head->setNext(newEl);
cout <<"IF"<<endl;
}else{
DoublyLinkedNode<T> *temp = head;
head = newEl;
newEl->setPrevious(nullptr);
newEl->setNext(temp);
temp->setPrevious(head);
cout << "El" << endl;
}
}
numberOfElements++;
return head;
}
This bit of the loop (which I guess is trying to print out the items)... is wrong. The while part loops over the data while it works on elements
Your broken code :
while(temp->getData() != nullptr){
temp = temp->getNext();
t++;
cout << t << endl;
}
Somewhat more functional :
while(temp != nullptr){
cout << t << ":" << temp->getData() << endl;
temp = temp->getNext();
++t;
}
It doesn't solve your sorting problem, but as you said above, you are going iteratively, so I leave that for you to work out.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
my code stop working in that test case, i think that the error in function Checktables but i'm not sure and i can't fix the error please help me to tun this code correctly.
image of a test case and the error
this is a cpp file with main .cpp
#include"Header.h"
string Name;
string namess;
customer::customer()
{
name = "";
gsize = status = 0;
next = NULL;
}
customer::customer(string name1, int gsize1, int status1)
{
name = name1;
gsize = gsize1;
status = status1;
next = NULL;
}
waitinglist::waitinglist()
{
chairnum =50 ;
totalcustomers = tables = 0;
head = tail = NULL;
}
waitinglist::waitinglist(int val)
{
chairnum = 50;
totalcustomers = 0;
tables = 0;
head = tail = NULL;
}
void waitinglist::change()
{
customer*temp ;
temp = head;
cout << "enter the name: ";
cin >> namess;
while (temp != NULL)
{
if (namess == temp->name)
{
if (temp->status==2)
{
temp->status=1;
cout << "done! " << endl ;
break ;
}
}
else if (namess != temp->name)
{
temp = temp->next;
}
}
if (temp == NULL)
{
cout << "can't found! " << endl;
}
}
void waitinglist::newcustomer()
{
customer*tmp = new customer;
cout << "enter the name: "; cin >> tmp->name;
customer*tmpo=new customer;
tmpo=head ;
while (tmpo != NULL)
{
if (tmp->name != tmpo->name)
{
tmpo = tmpo->next;
}
else if (tmp->name == tmpo->name)
{
cout<<"The Name already exist! " << endl ;
cout << "enter the name: "; cin >> tmp->name;
tmpo=head;
}
}
cout << "enter the group number: "; cin >> tmp->gsize;
cout << "enter the status: "; cin >> tmp->status;
if (head == NULL) // linkedlist is empty
{
head = tail = tmp;
totalcustomers++;
}
else
{
tail->next = tmp;
tail=tail->next;
totalcustomers++;
}
}
void waitinglist::checktables()
{
float c=5.00;
customer*temp=head;
customer*found;
cout<<"enter number of tables: ";
cin >> tables ;
while (tables>=1 && temp!=NULL)
{
int x;
float y;
y=((temp->gsize)/c);
x=(temp->gsize)/c;
if (tables<y)
{
temp=temp->next;
}
else if (tables>=y)
{
if (x==y)
{
tables=tables-x ; // Correct Table!
cout<<temp->name<<endl;
}
else if (x!=y)
{
tables=tables-(x+1);
cout<<temp->name<<endl;
}
found=temp ;
delete found; // Discard
break ;
}
}
}
void waitinglist::displayall()
{
customer *tmp;
tmp = head;
if (tmp == NULL)
{
cout << "Empty!";
}
while (tmp != NULL)
{
cout << "Name: " << tmp->name <<endl;
cout << "group number: " << tmp->gsize << endl;
tmp = tmp->next;
}
cout << endl;
}
void waitinglist::diplaycustomer()
{
customer*tmp;
tmp = head;
cout << "enter the name: ";
cin >> Name;
while (tmp != NULL)
{
if (Name == tmp->name)
{
cout << "the name : " << tmp->name << endl;
cout << "the group size = " << tmp->gsize << endl;
cout << "the status = " << tmp->status << endl;
break;
}
else if (Name != tmp->name)
{
tmp = tmp->next;
}
}
if (tmp == NULL)
{
cout << "can't found!" << endl;
}
}
int main()
{
int choice;
string name1 = "";
int gsize1 = 0;
int status1 = 0;
waitinglist mylist;
cout << "Note: 1 in status means the customer not here and 2 means the customer is here.\n";
cout << "Select your option.\n\n";
cout << "(1) Add a new Customer.\n";
cout << "(2) Display information based on Name.\n";
cout << "(3) List all Names.\n";
cout << "(4) to change the status. \n" ;
cout << "(5) Check tables by name. \n";
cout << "(6) quit. \n";
do
{
cout << "\n";
cout << "Enter your choice: --> ";
cin >> choice;
if (1 <= choice && choice <= 5)
{
switch (choice)
{
case 1:
mylist.newcustomer();
break;
case 2:
mylist.diplaycustomer();
break;
case 3:
mylist.displayall();
break;
case 4:
mylist.change() ;
break;
case 5 :
mylist.checktables();
break;
default:
cout << "Invalid choice. Enter again.\n\n";
break;
}
}
else if (choice>6)
{
cout << "Invalid choice. Enter again.\n\n";
break;
}
} while (choice != 6);
return 0;
}
and this is the header file .h
#include<iostream>
#include<string>
using namespace std;
class customer
{
public:
string name;
int gsize;
int status;
customer* next;
customer();
customer(string,int,int);
};
class waitinglist
{
public:
int tables; //number of occupied tables
int chairnum;
int totalcustomers;
customer*head,*tail;
waitinglist();
waitinglist(int);
void newcustomer();
void diplaycustomer();
void displayall();
void change () ;
void checktables();
};
One error is that your checktables function corrupts your linked list structure by calling delete on one of the nodes:
found = temp;
delete found; // Discard
What you've just done in those lines above is to have a linked list with a broken (invalid) link in it. Any functions that now traverses the list (like displaytables) will now hit the broken link, and things start to go haywire.
To delete a node from a linked list, you have to not just call delete, but adjust the link in waitinglist that used to point to that deleted node and have it point to the next node after the deleted one.
Think of it like a real chain -- if one of the links in the chain needs to be removed, you have to physically remove it, and hook the link before it to the next good link. You didn't do this step.
I won't write the code for that, but this is what you should have seen much earlier in the development of your program. Better yet would have been to write a singly-linked list class that adds and removes nodes correctly first. Test it, and then once it can add and remove nodes successfully without error, then use it in your larger program.
I'm working on my first multilist and it has been nothing but a nightmare so far. Right now, I am allowing the user to place the x,y spots (class_number,student_number) in on their own. My node looks like this:
typedef struct node {
int student_number;
int class_number;
struct node* classpointer;
struct node* studentpointer;
}* nodePtr;
Initialized with
List::List() {
head = nullptr;
currClass = nullptr;
currStudent = nullptr;
}
To add in the data values and set up pointers I have two functions.
void List::addNodeToClass() {
nodePtr n = new node;
n->classpointer = NULL;
cout << "What class number would you like to add?" << endl;
int x;
cin >> x;
n->class_number = x;
if(head != NULL) {
currClass = head;
while (currClass->classpointer != NULL) {
currClass = currClass->classpointer;
}
currClass->classpointer = n;
}
else {
head = n;
}
}
And
void List::addNodeToStudent() {
nodePtr n = new node;
n->studentpointer = NULL;
cout << "What student number would you like to add?" << endl;
int x;
cin >> x;
n->student_number = x;
if(head != NULL) {
currStudent = head;
while (currStudent->studentpointer != NULL) {
currStudent = currStudent->studentpointer;
}
currStudent->studentpointer = n;
}
else {
head = n;
}
}
I make function calls to both of these functions in my menu() function, and in main() I only call for menu()
int menu() {
int input;
List List;
while (input != 3) {
cout << " " << endl;
cout << "Press '1' to input a node" << endl;
cout << "Press '2' to view the list of nodes" << endl;
cout << "Press '3' to exit" << endl;
cout << " " << endl;
cin >> input;
if (input == 1) {
List.addNodeToClass();
List.addNodeToStudent();
}
else if (input == 2) {
List.PrintList();
}
else if (input == 3) {
return 0;
}
else {
cout <<"That is an invalid key" << endl;
}
}
}
When I run the program I am able to input the class node, then when I go to enter the student node, after hitting enter the program crashes. I know that there is a lot to look through, but I can't understand why it is. If someone would be able to tell me what I am doing wrong here I would greatly appreciate it. Thank you.
The addNodeToClass function never sets node->studentpointer. So when you follow that pointer in addNodeToStudent, you are dereferencing garbage.
Your code would be safer with a default node constructor:
typedef struct node {
node()
{
student_number = 0;
class_number = 0;
classpointer = nullptr;
studentpointer = nullptr;
}
int student_number;
int class_number;
struct node* classpointer;
struct node* studentpointer;
}* nodePtr;
And this would fix your issue because those attributes are not always initialized in your code (new node does not initialize the node attributes if there is no such constructor).
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Closed 8 years ago.
Improve this question
I am new to c++ , trying to write singly linked list in c++ , and it's various operations like , print, insert at the end, insert the end, delete etc. I am doing step by step. I have written my first insert method. It is working fine no error , but the first time it goes to the if condition of insert i.e the list is empty and create the first node here the problem is coming is after entering the first node the output screen is closing saying "project has stopped working" . what I am trying to do is after entering one node it should ask "do u wish to add another node?" if users enter "y" it should continue otherwise should go back to main function : Here is my code :
#include <iostream>
using namespace std;
struct node
{
int num;
node *next;
};
class link_list
{
node *head;
node *list;
public:
link_list()
{
head = NULL;
list = NULL;
//cout << list;
}
// void display_options(link_list &b);
void print_list();
void insert();
//void insert_at_beg();
// void insert_at_middle();
};
void link_list::print_list()
{
if (list == NULL)
{
cout << "Empty list" << endl;
//return;
}
else
{
int count = 0;
while (list->next != NULL)
{
list = list->next;
count++;
cout << "Node " << "value " << endl;
cout << count << " " << list->num << endl;
}
}
}
void link_list::insert()
{
// head = new node;
//list = head;
int y;
char a;
do
{
if (head == NULL)
{
head = new node;
cout << "enter the first node" << endl;
cin >> y;
list->num = y;
list->next = NULL;
}
else
{
node * newNode;
list == head;
while (list->next != NULL)
{
list->next = list;
}
newNode = new node;
cin >> y;
newNode->num = y;
list->next = newNode;
newNode->next = NULL;
}
cout << "do u wish to add another node?" << endl;
cin >> a;
} while (a == 'y' || a == 'Y');
}
int main()
{
link_list ll;
char choice;
do{
cout << "select one" << endl;
cout << "press 1 for insert ." << endl;
cout << "press 2 for insert at beginning ." << endl;
cout << "press 3 for insert at the middle ." << endl;
cout << "press 4 delete ." << endl;
cout << "print 5 print the linked list :" << endl;
cout << "print 6 exit :" << endl;
int no;
cin >> no;
switch (no)
{
case 1:
ll.insert();
break;
case 5:
ll.print_list();
case 6:
return 0;
default:
cout << "oops wrong choice" << endl;
}
fflush(stdin);
cout << "Do u wanna make another choice?" << endl;
cin >> choice;
cout << choice << endl;
} while (choice == 'Y' || choice == 'y');
cout << "Thanks!" << endl;
system("pause");
return 0;
}
You need to keep a more careful eye on your compiler warnings, and you need to learn how to use a debugger. There are many problems with this code, but most of them are easy to find by debugging.
This line in link_list::insert is not an assignment, it is a comparison. This would likely be raised as a compiler warning in most modern compilers. You'll probably want to fix that.
line == head
This loop doesn't do anything useful:
while (list->next != NULL)
{
list->next = list;
}
If list starts off as non-null, all this code will do is loop forever, repeatedly setting list->next to list. You probably wanted the operation to be the other way around.
list = list->next;
which will get you the last element in the list.
Still in the same function, this is broken:
head = new node;
cout << "enter the first node" << endl;
cin >> y;
list->num = y;
list->next = NULL;
because you haven't initialised list. Using head instead of list is probably what you wanted.
This is silly:
newNode = new node;
cin >> y;
because you don't prompt for the node value.
Once these changes are made, the code appears to function, at least for insertion and printing, but I'm not going to investigate further.
Perhaps this might be better moved to https://codereview.stackexchange.com/
head = new node;
cout << "enter the first node" << endl;
cin >> y;
list->num=y; //<-- problem
You are using list without initializing it. You should write
list = head;
before the statement list->num=y;
This will fix the bug for first time insertion. but there are several other problems in you code while inserting subsequently, which is pointed out by other answers. Modified code will be
void link_list::insert()
{
int y;
char a;
do
{
if (head == NULL)
{
head = new node;
cout << "enter the first node" << endl;
cin >> y;
head->num = y;
head->next = NULL; // no need to list as a member at all
}
else
{
node* list = head;
while (list->next != NULL)
{
list= list->next;
}
list->next= new node;
cin >> y;
list->next->num = y;
list->next->next = NULL;
}
cout << "do u wish to add another node?" << endl;
cin >> a;
} while (a == 'y' || a == 'Y');
}
void link_list::print_list()
{
if (head == NULL)
{
cout << "Empty list" << endl;
//return;
}
else
{
int count = 0;
node* list=head;
while (list->next != NULL)
{
count++;
cout << "Node " << "value " << endl;
cout << count << " " << list->num << endl;
list = list->next;
}
}
}