Hey there! I've been working on this code that uses linked list operations:
#include<iostream>
#include<conio.h>
using namespace std;
void displayRecords(); // done
void searchRecord(string); // done
void insertAtEnd(string, string, int); // done
void insertAtBeginning(string, string, int); // done
void insertAtSpecifiedLocation (string, string, int, int); // done
void deleteAtEnd(); // somewhat working. trouble happens when there's only one entry. than again, i fixed it. :3
void deleteAtBeginning(); // done
void deleteAtSpecifiedLocation(int); // somewhat working. program crashes when an invalid value is entered.
void isHeadNull(struct node*); // just to make the code a few lines shorter,
struct node {
string name;
string address;
int number;
struct node *next;
}
*head = NULL;
int main() {
char loop = '\0';
string name = "", address = "";
int choice = 0, number = 0, position = 0;
do
{
cout << "\nLinked List Operations" << endl;
cout << "MENU:" << endl;
cout << "[1] Display all records" << endl;
cout << "[2] Search for a record (by name)" << endl;
cout << "[3] Insert a new record at the end of the list" << endl;
cout << "[4] Insert a new record at the beginning of the list" << endl;
cout << "[5] Insert a new record at a specified location" << endl;
cout << "[6] Delete the record at the end of the list" << endl;
cout << "[7] Delete the record at the beginning of the list" << endl;
cout << "[8] Delete a record at a specified location" << endl;
cout << "[9] Quit" << endl;
cout << "Enter your choice: ";
cin >> choice;
if (choice == 1)
{
isHeadNull(head);
displayRecords();
}
else if (choice == 2)
{
isHeadNull(head);
cout << "Name in entry: ";
getline(cin, name);
getline(cin, name);
searchRecord(name);
}
else if (choice == 3)
{
cout << "Enter name: ";
getline(cin, name);
getline(cin, name);
cout << "Enter address: ";
getline(cin, address);
cout << "Enter number: ";
cin >> number;
insertAtEnd(name, address, number);
}
else if (choice == 4)
{
cout << "Enter name: ";
getline(cin, name);
getline(cin, name);
cout << "Enter address: ";
getline(cin, address);
cout << "Enter number: ";
cin >> number;
insertAtBeginning(name, address, number);
}
else if (choice == 5)
{
cout << "Enter name: ";
getline(cin, name);
getline(cin, name);
cout << "Enter address: ";
getline(cin, address);
cout << "Enter number: ";
cin >> number;
cout << "Position: ";
cin >> position;
insertAtSpecifiedLocation(name, address, number, position);
}
else if (choice == 6)
{
isHeadNull(head);
deleteAtEnd();
}
else if (choice == 7)
{
isHeadNull(head);
deleteAtBeginning();
}
else if (choice == 8)
{
isHeadNull(head);
cout << "Record number you'd want to delete: ";
cin >> position;
deleteAtSpecifiedLocation(position);
}
else if (choice == 9)
return 0;
cout << "Try again [Y/N]? ";
cin >> loop;
}
while (toupper(loop) == 'Y');
return 0;
}
void displayRecords() {
int counter = 1;
struct node *movingPointer = head;
cout << endl;
while (movingPointer != NULL)
{
cout << "RECORD #: " << counter << endl;
cout << " Name: " << movingPointer->name << endl;
cout << " Address: " << movingPointer->address << endl;
cout << " Number: " << movingPointer->number << endl;
movingPointer = movingPointer->next;
++counter;
}
cout << endl;
}
void searchRecord(string name)
{
int position = 0;
struct node *movingPointer = head;
while (movingPointer != NULL)
{
++position;
if (movingPointer->name == name)
{
cout << "Record #: " << position << endl;
return;
}
movingPointer = movingPointer->next;
}
cout << "Record does not exist." << endl;
return;
}
void insertAtEnd(string name, string address, int number)
{
struct node *temp;
if (head == NULL)
{
temp = (struct node*)malloc(sizeof(struct node));
temp->name = name;
temp->address = address;
temp->number = number;
temp->next = NULL;
head = temp;
}
else
{
struct node *movingPointer = head;
while (movingPointer->next != NULL)
{
movingPointer = movingPointer->next;
}
temp = (struct node*)malloc(sizeof(struct node));
temp->name = name;
temp->address = address;
temp->number = number;
temp->next = NULL;
movingPointer->next = temp;
}
}
void insertAtBeginning(string name, string address, int number)
{
struct node *temp;
temp = (struct node*)malloc(sizeof(struct node));
temp->name = name;
temp->address = address;
temp->number = number;
temp->next = head;
head = temp;
}
void insertAtSpecifiedLocation (string name, string address, int number, int position)
{
struct node *temp, *movingPointer = head;
for (int i=1; i < position-1; i++)
{
movingPointer = movingPointer->next;
if(movingPointer == NULL)
{
cout << "Record # " << position << " does not exist. Please create a sufficient amount of records first." << endl;
return;
}
}
temp = (struct node*)malloc(sizeof(struct node));
temp->name = name;
temp->address = address;
temp->number = number;
temp->next = movingPointer->next;
movingPointer->next = temp;
}
void deleteAtEnd()
{
struct node *movingPointer = head, *previousNode = NULL;
while (movingPointer->next != NULL)
{
previousNode = movingPointer;
movingPointer = movingPointer->next;
}
if (previousNode == NULL) // if list has only one entry
{
free(movingPointer);
head = NULL;
cout << "Record has been deleted." << endl;
return;
}
previousNode->next = NULL;
free(movingPointer);
cout << "Record has been deleted." << endl;
}
void deleteAtBeginning()
{
struct node *nodeToRemove = head;
head = nodeToRemove->next;
free(nodeToRemove);
cout << "Record # 1 has been deleted." << endl;
}
void deleteAtSpecifiedLocation(int position)
{
struct node *movingPointer = head, *previousNode = NULL;
for (int i=1; i < position; i++)
{
previousNode = movingPointer;
movingPointer = movingPointer->next;
if (movingPointer == NULL)
{
cout << "Record #" << position << " does not exist. Please enter a valid value." << endl;
return;
}
}
if (previousNode == NULL) // if list has only one entry
{
head = movingPointer->next;
free(movingPointer);
cout << "Record #" << position << " has been successfully deleted." << endl;
return;
}
previousNode->next = movingPointer->next;
free(movingPointer);
cout << "Record #" << position << " has been successfully deleted." << endl;
}
void isHeadNull (struct node *head)
{
if (head == NULL)
{
cout << "\n****************************************************************\n";
cout << "This list is empty. Please create a sufficient amount of records\n";
cout << "in order to use this function." << endl;
cout << "****************************************************************\n";
main();
}
}
So, I think I did well on the linked list operations code. I think they do what they're supposed to do. However, my trouble here is with, I think, the main() and the isHeadNull() function. My isHeadNull() function prints the error message in case the user of the program tries to use a linked list operation that applies only if the linked list has contents. But I noticed something quite odd: assuming that I have an empty list, and if I were to choose the option [2] - which is for searching records - in the MENU, of course, my error message is supposed to appear and then, main() gets called to restart everything (hopefully) and I am asked to choose from the options again. However, if I then proceed to choose option [9] - quit - it doesn't quit/terminate the program. It actually continues to do what option [2] is supposed to do. The photos below summarize what happens:
This event applies to an empty list and a user calling on for-lists-with-contents-only functions (options 1, 2, 6, 7, 8). Then choosing option 9. I think this has something to do with resetting values, or possibly, the main() function calling the isHeadNull() function calling the main() function... or something like that.