Merging 3 lists in one big list - c++

So I have a few lists(HeadFirstCl, HeadNoSm, HeadSm) that I want to connect and make a big list (HeadByPlace) while the pointers for the others still remain. My question is why does my ConnectLists function not work?
#include <iostream>
#include <string>
using namespace std;
struct Item {
string naprav;
string chasizl;
string chaskac;
int termizl;
int termkac;
char fime[5];
int mqsto;
Item *NextByPlace;
};
typedef Item *Point;
Point HeadByPlace, HeadFirstCl, HeadNoSm, HeadSm;
void ConnectLists(Point &P, Point A) {
while (A) {
if (P->NextByPlace == NULL)
P->NextByPlace = A;
P = P->NextByPlace;
}
}
void PrintOut(Point P) {
while (P) {
cout << P->fime<<endl;
cout << P->chasizl << endl;
cout << P->chaskac << endl;
cout << P->mqsto << endl;
cout << P->naprav << endl;
cout << P->termizl << endl;
cout << P->termkac << endl;
P = P->NextByPlace;
}
}
void Create(Point &Head, int i) {
Point Last, P;
Last = NULL;
P = new Item;
P->mqsto = i;
cout << "Enter destination" << endl;
cin >> P->naprav;
cout << "Enter departure HOUR" << endl;
cin >> P->chasizl;
cout << "Enter arrival HOUR" << endl;
cin >> P->chaskac;
cout << "Enter # of leaving terminal" << endl;
cin >> P->termizl;
cout << "Enter # of entering terminal" << endl;
cin >> P->termkac;
cout << "Last name of traveler" << endl;
cin >> P->fime;
P->NextByPlace = NULL;
if (Head == NULL) {
Head = P;
} else {
Last->NextByPlace = P;
}
Last = P;
}
void Delete(char name[], Point &Head) {
Point Pprev, P;
P = new Item;
Pprev = new Item;
cin >> name;
while (Head) {
if (strcmp(Head->fime, name) == 1) {
Pprev = P->NextByPlace;
*P = *Pprev;
delete Pprev;
}
}
}
void main() {
char ch;
HeadByPlace = NULL;
HeadFirstCl = NULL;
HeadNoSm = NULL;
HeadSm = NULL;
int i;
cout << "New element? (Y/N)? : ";
cin >> ch;
while (ch == 'Y' || ch == 'y') {
cout << "Enter seat #: ";
cin >> i;
if (i < 7) Create(HeadFirstCl,i);
else if (i > 7 && i < 25) Create(HeadNoSm,i);
else if (i > 25) Create(HeadSm,i);
cout << " New element? (Y/N) ?: ";
cin >> ch;
}
ConnectLists(HeadByPlace, HeadFirstCl);
ConnectLists(HeadByPlace, HeadNoSm);
ConnectLists(HeadByPlace, HeadSm);
PrintOut(HeadByPlace);
system("pause");
}

I think I found some of your problems. Your connect list function has one main issue, your while loop never terminates. In C++, the implicit conversion from a pointer to a bool returns true if the pointer is not null, and false if the pointer is null. Your loop checks infinitely to see if A is null or not. Obviously, if you give the function a null pointer, it won't do anything, but if you give it a valid pointer for A, it will loop forever because A isn't being changed in the function. Here's a simple function that will actually combine your lists without this issue:
void ConnectLists(Point P, Point A) {
while (P->NextByPlace != nullptr) {
P = P->NextByPlace;
}
P->NextByPlace = A;
}
This function loops until the end of the list, then adds A to the end. Note that it doesn't do any error handling for situations where A or P are null. If you replace your function with this one, it will do what you asked.
There are also very fundamental problems with the code you provided. Your create function segfaults if you make more than one entry of the same type. Also, your test case is flawed. You are passing the connectLists function the pointer HeadByPlace for P each time it is called. HeadByPlace is null so attempting to access any of it's values, such as nextByPlace, results in a segmentation fault. If you want to make sure the code for the connectLists function I provided works, initialize one of each of your list types (HeadFirstCl, HeadNoSM, and HeadSM) and try to connect those, or simply allocate memory for HeadByPlace.
Also, I have one piece of unsolicited advice. You may want to take a look at the C++ STL containers: http://www.cplusplus.com/reference/stl/. I think some of these data structures, such as the vector or list, may be useful to you for this project.

Related

Queue linked list not printing it's contents

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.

Trying to understand why my linked list only show the last added node

So i'm lost right now the idea was to make a linked list where the user can add multiple school subjects and it needs to be displayed at the end but what i get is the last inserted subject and it's infromation at the end. Maybe someone can help?
#include <iostream>
using namespace std;
struct cvor {
int sif_pred;
string naz_pred;
int br_sati_pr;
int br_sati_vj;
cvor* veza; //veza=link
} faks;
void unos(cvor*& glava, cvor* noviPredmet) //glava=head
{
noviPredmet->sif_pred = faks.sif_pred;
noviPredmet->naz_pred = faks.naz_pred;
noviPredmet->br_sati_pr = faks.br_sati_pr;
noviPredmet->br_sati_vj = faks.br_sati_vj;
noviPredmet->veza = glava;
glava = noviPredmet;
}
void ispis(cvor*& glava)
{
while (glava) {
cout << glava->sif_pred << " ";
cout << glava->naz_pred << " ";
cout << glava->br_sati_pr << " ";
cout << glava->br_sati_vj << " ";
glava = glava->veza;
}
}
int main()
{
cvor* glava = 0;
cvor* noviPredmet = new cvor;
int x;
do {
do {
cout << "Unesti sifru predavanja: ";
cin >> faks.sif_pred;
cout << "\nUnesti naziv predavanja: ";
cin >> faks.naz_pred;
cout << "\nUnesti broj stai predavanja: ";
cin >> faks.br_sati_pr;
cout << "\nUnesti broj stai vjezbi: ";
cin >> faks.br_sati_vj;
} while (faks.br_sati_vj != 0);
unos(glava, noviPredmet);
cin >> x;
} while (x != 0);
ispis(glava);
return 0;
}
You only allocate one node, here:
cvor* noviPredmet = new cvor;
Then, every time, you add that very same node to the list:
unos(glava, noviPredmet);
#DavidSchwartz is right, you should move this line in your code
cvor* noviPredmet = new cvor;
a couple of lines down, sandwiched between to two do commands and it should work as expected.
What is the role of variable x that breaks the outer loop?
I have noticed that the code will print only the nodes that have been inserted in the last outer loop, the one with x = 0.

Linked List and inserting a string in alphabetical order

I'm writing a program that allows a user to insert, delete, search, and print books. The books must print out in alphabetical order. When I'm inserting books, it works just fine but it does not put them in the right order and it will crash. Here is my code for the insert function.
void BookList::Insert(Book* nBook)
{
string name;
int quant;
double p;
cout << "Enter the title of the book." << endl;
cin.ignore();
getline(cin, name);
cout << "Enter the number of quanities of this book." << endl;
cin >> quant;
cout << "Enter the price of this book." << endl;
cin.ignore();
cin >> p;
nBook->title = name;
nBook->quantity = quant;
nBook->price = p;
nBook->next = nullptr;
//cout << "test" << endl;
//If the current book is lexicographically smallest.
if (first == nullptr) {
first = nBook;
cout << first->title << endl;
}
else if (nBook->title <= first->title)
{
cout << "new first" << endl;
nBook->next = first;
first = nBook;
}
else
{
cout << first->title << endl;
//if current book is lexicographically small between two books.
Book* prevPtr = first;
while (prevPtr != nullptr)
{
cout << "Looking at: " << prevPtr->title << endl;
if (prevPtr->title > nBook->title)
{
break;
}
else
{
prevPtr = prevPtr->next;
}
}
nBook->next = prevPtr->next;
prevPtr->next = nBook;
}
}
P.S. This is in C++
Thank you
Just because something doesn't show an error at compile doesn't mean it works fine.
Why are you using cin.ignore() with no parameters? What is the single character you are trying to ignore? You realize cin >> (someint or somedouble) already ignores whitespace and return characters, right?
More of your code is needed for context, but it seems like you're trying to fill the information for the new book into a "nBook" node before you actually initialize a new "nBook" node.
Also, I suggest not putting that output at the end in the method. If your method is for adding a new book to your linklist, just use it to add it. Put those outputs in a separate method, or in the calling method. (or maybe you just put those in for debugging purposes, in which case nvm)
Just my 0.02

Singly linked list , project stops working [closed]

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;
}
}
}

Printing out linked list elements

I wrote a program that adds elements recursively, and then prints out the elements. The problem is, that the program prints out only the first element in the list. I tried to solve this, but I don't know where is the problem...
#include <iostream>
using namespace std;
struct list
{
int value;
list* next;
};
list* addNewElement(list* p_head, int elems)
{
if (elems >= 1)
{
list* p_list = new list;
cout << "Enter a value: ";
cin >> p_list->value;
p_list->next = p_head;
addNewElement(p_head, elems - 1);
return p_list;
}
}
void printList(list* p_head)
{
list* p_cur = p_head;
cout << "ELEMENTS: " << endl;
while (p_cur != NULL)
{
cout << p_cur->value;
p_cur = p_cur->next;
}
cout << endl;
}
int main()
{
list* p_head = NULL;
int elemNR;
cout << "Enter how many elements do you want in the list: ";
cin >> elemNR;
p_head = addNewElement(p_head, elemNR);
cout << endl;
printList(p_head);
cout << endl;
cout << "PRESS <ENTER> TO CONTINUE...";
cin.ignore();
cin.get();
}
The problem is that after all iterations You have a lot of list objects in which next pointer points to NULL. You should modify your addNewElement method to something like this:
list* addNewElement(list* p_head, int elems) {
if (elems >= 1) {
list* p_list = new list;
cout << "Enter a value: ";
cin >> p_list->value;
p_list->next = addNewElement(p_head, elems - 1);
return p_list;
}
return p_head;
}
What had changed? p_list->next pointer is being set to the beginning of next list's element instead of NULL ;)
EDIT: Here is working code: http://ideone.com/oJ8kX7