Delete the last remaining node in a link list - c++

I am making this function that deletes an element inside of a list. The problem is when I delete the last remaining node of the list it gives me back nothing. To be precise, let's say we have a link list
head -> node_1 -> node_2 -> NULL
I want to delete all of the items inside the list hence " head -> NULL; "
void delete_item(NODE **start,int *last){
NODE *before, *discard;
int delete_value;
if(is_empty(*start) == 1){
cout << endl << "THE LIST IS EMPTY";
}else{
discard = *start;
print_items(*start);
cout << endl << "What item would you like to delete?: ";
cin >> delete_value;
if((*start)->next == NULL){
cout << endl <<"entered" << endl;
delete *start;
*start = NULL;
--*last;
}
//if delete value is in the first node
if((*start)->value == delete_value){
*start = (*start)->next;
(*start)->prev = NULL;
free(discard);
--*last;
cout << endl << "ITEM SUCCESSFULLY DELETED!";
}else{
int index{1};
//searches for the value
while(discard != NULL && discard->value != delete_value){
before = discard;
discard = discard->next;
++index;
}
if(discard == NULL){
cout << endl<< "ITEM DOES NOT EXIST TRY AGAIN!" << endl;
}else{
//if item is in the last node of the list
if(index == *last){
before->next = NULL;
free(discard);
--*last;
cout << endl << "ITEM SUCCESSFULLY DELETED!" << endl;
}else{
//if item is in between the list
discard->next->prev = before->next;
before->next = discard->next;
free(discard);
--*last;
cout << endl << "ITEM SUCCESSFULLY DELETED!" << endl;
}
}
}
}
}

It is always best to delete a given node in a seperate function and then call that function according to your requirement. You can find that kind of code in any coding website.
However, I did not want to discourage your method. So I am editing your code only.
void delete_item(NODE **start,int *last){
NODE *before, *discard;
int delete_value;
if(is_empty(*start) == 1){
cout << endl << "THE LIST IS EMPTY";
}else{
discard = *start;
print_items(*start);
cout << endl << "What item would you like to delete?: ";
cin >> delete_value;
//if delete value is in the first node
if((*start)->value == delete_value){
*start = (*start)->next;
(*start)->prev = NULL;
free(discard);
--*last;
cout << endl << "ITEM SUCCESSFULLY DELETED!";
}else{
int index{1};
//searches for the value
while(discard != NULL && discard->value != delete_value){
before = discard;
discard = discard->next;
++index;
}
if(discard == NULL){
cout << endl<< "ITEM DOES NOT EXIST TRY AGAIN!" << endl;
}else{
//if item is in the last node of the list
if(index == *last){
before->next = NULL;
free(discard);
--*last;
cout << endl << "ITEM SUCCESSFULLY DELETED!" << endl;
}else{
//if item is in between the list
discard->next->prev = before;
before->next = discard->next;
free(discard);
--*last;
cout << endl << "ITEM SUCCESSFULLY DELETED!" << endl;
}
}
}
}
}

Related

Deletion in Binary Search Tree for strings

This program is a binary search tree of string to store information of students with the following details such as id, name and CGPA. And using unique id of a student to search, delete and insert different data. But in deletion when a subtree is involved the tree gets separated, I don't know what I'm doing wrong.
#include <iostream>
using namespace std;
struct BstNode
{
string iD;
string name;
float cgpa;
BstNode *left;
BstNode *right;
};
BstNode *root;
BstNode *GetNewNode(string iD0, string n0, float cg0)
{
BstNode *NewNode = new BstNode();
NewNode->iD = iD0;
NewNode->name = n0;
NewNode->cgpa = cg0;
NewNode->left = NULL;
NewNode->right = NULL;
return NewNode;
}
void PreOrder(BstNode *root)
{
if (root == NULL)
{
return;
}
cout << "ID: " << root->iD << "\nNAME: " << root->name << "\nCGPA: " << root->cgpa << endl;
PreOrder(root->left);
PreOrder(root->right);
}
void InOrder(BstNode *root)
{
if (root == NULL)
{
return;
}
InOrder(root->left);
cout << "ID: " << root->iD << "\nNAME: " << root->name << "\nCGPA: " << root->cgpa << endl;
InOrder(root->right);
}
void PostOrder(BstNode *root)
{
if (root == NULL)
{
return;
}
PostOrder(root->left);
PostOrder(root->right);
cout << "ID: " << root->iD << "\nNAME: " << root->name << "\nCGPA: " << root->cgpa << endl;
cout << endl;
}
BstNode *Insert(BstNode *root, string iD2, string n2, float cg2)
{
if (root == NULL)
{
root = GetNewNode(iD2, n2, cg2);
}
else if (iD2 <= root->iD)
{
root->left = Insert(root->left, iD2, n2, cg2);
}
else
{
root->right = Insert(root->right, iD2, n2, cg2);
}
return root;
}
BstNode *Rectify(BstNode *root, string id1, string n, float cg)
{
root->iD = id1;
root->name = n;
root->cgpa = cg;
return root;
}
struct BstNode *FindMin(BstNode *root)
{
struct BstNode* current = root;
/* loop down to find the leftmost leaf */
while (current && current->left != NULL)
current = current->left;
return current;
}
BstNode *Delete(BstNode *root, string data)
{
if (root == NULL)
return root;
else
{
if (data < root->iD)
root->left = Delete(root->left, data);
else if (data > root->iD)
root->right = Delete(root->right, data);
else
{
if (root->left == NULL and root->right == NULL)
return NULL;
else if (root->left == NULL)
{
struct BstNode *temp = root->right;
delete(root);
return temp;
}
else if (root->right == NULL)
{
struct BstNode *temp = root->left;
delete(root);
return temp;
}
else
{
struct BstNode *temp = FindMin(root->right);
root->iD = temp->iD;
root->name = temp->name;
root->cgpa = temp->cgpa;
root->right = Delete(root->right, temp->iD);
}
}
return root;
}
}
BstNode *Search(BstNode * root, string iDs)
{
cout << "Finding " << endl;
if (root == NULL)
{
cout << "No such info!" << endl;
return root;
}
else if (root->iD == iDs)
{
cout << "Found 0 " << endl;
cout << "ID: " << root->iD << endl;
cout << "NAME: " << root->name << endl;
cout << "CGPA: " << root->cgpa << endl;
bool done = false;
while (!done)
{
cout << "Would you like to update this student's information? [y/n]\n";
string x;
cin >> x;
if (x == "y")
{
cout << "The following fields are updatable:\n";
cout << "1. Student ID\n";
cout << "2. Student Name\n";
cout << "3. Student CGPA\n";
cout << "4. Remove Student\n";
cout << "Enter your choice:\n";
bool done1 = false;
while (!done1)
{
int ch;
cin >> ch;
if (ch == 1)
{
cout << "Please enter new ID: \n";
string nwid;
cin >> nwid;
cout << "============================" << endl;
cout << "Updating \n";
cout << "============================" << endl;
root = Rectify(root, nwid, root->name, root->cgpa);
cout << "============================" << endl;
cout << "Updated Successfully! \n";
cout << "============================" << endl;
cout << "============================" << endl;
cout << root->iD << endl;
cout << root->name << endl;
cout << root->cgpa << endl;
cout << "============================" << endl;
done1 = true;
}
else if (ch == 2)
{
cout << "Please enter new name: \n";
string nwname;
cin >> nwname;
cout << "============================" << endl;
cout << "Updating \n";
cout << "============================" << endl;
root = Rectify(root, root->iD, nwname, root->cgpa);
cout << "============================" << endl;
cout << "Updated Successfully! \n";
cout << "============================" << endl;
cout << "============================" << endl;
cout << root->iD << endl;
cout << root->name << endl;
cout << root->cgpa << endl;
cout << "============================" << endl;
done1 = true;
}
else if (ch == 3)
{
cout << "Please enter new CGPA: \n";
float nwcg;
cin >> nwcg;
cout << "============================" << endl;
cout << "Updating \n";
cout << "============================" << endl;
root = Rectify(root, root->iD, root->name, nwcg);
cout << "============================" << endl;
cout << "Updated Successfully! \n";
cout << "============================" << endl;
cout << "============================" << endl;
cout << root->iD << endl;
cout << root->name << endl;
cout << root->cgpa << endl;
cout << "============================" << endl;
done1 = true;
}
else if (ch == 4)
{
cout << "Removing\n";
root = Delete(root, root->iD);
cout << "Removed!\n";
return root;
done1 = true;
}
else
{
cout << "Wrong input try again! \n";
}
}
done = true;
}
else if (x == "n")
{
done = true;
}
else
{
cout << "Wrong input try again! \n";
}
}
return root;
}
else if (iDs <= root->iD)
{
return Search(root->left, iDs);
}
else
{
return Search(root->right, iDs);
}
}
int main()
{
root = NULL;
root = Insert(root, "21-44631-1", "Rafiul", 3.75);
root = Insert(root, "21-44531-1", "Haque", 4.0);
root = Insert(root, "21-44431-1", "Rafsun", 3.78);
root = Insert(root, "21-44331-1", "Rafi", 3.5);
root = Insert(root, "21-44231-1", "ABC", 4.0);
root = Insert(root, "21-44611-1", "AC", 4.0);
cout << "Please enter the ID you want to search: ";
string s;
cin >> s;
cout << endl;
Search(root, s);
cout << "Reading tree in preorder : \n";
PreOrder(root);
cout<<"============================"<< endl;
cout << "\nReading tree in inorder : \n";
InOrder(root);
cout<<"============================"<< endl;
cout << "\nReading tree in postorder : \n";
PostOrder(root);
cout << "============================" << endl;
}
Deleting a BST node from a simple (e.g. non-self-balancing) implementation involves three things:
Find the node you're deleting. More specifically, find the pointer in the tree (which may be the root pointer) that points to the node you want to delete.
Once found, promote one of the children to occupy the vacancy about to be left by the node being deleted.
Hang the opposite child (if there even is one) in the left (or right, depending on which child you promoted in (2), position possible of the promoted child.
Note that it is possible to cover all four node+children cases (no children, only a left child, only a right child, or both), using a single algorithm, especially when using a pointer-to-pointer to iterate the tree. It is done like this (liberally commented to try and explain what is going on):
BstNode *Delete(BstNode *root, string data)
{
BstNode **pp = &root;
// find the node we want to delete by id
while (*pp)
{
if (data < (*pp)->iD)
pp = &(*pp)->left;
else if ((*pp)->iD < data)
pp = &(*pp)->right;
else // equivalent. fount it
break;
}
// if this is non-null, we found the pointer in the
// tree that points to the node we want to delete.
// note that this could even be the root pointer
// where we started.
if (*pp)
{
// remember the node. we're about to overwrite
// the tree pointer that is referring to it.
BstNode *victim = *pp;
// always promote the right node.
*pp = victim->right;
// now iterate down the opposite side of the
// note we just promoted, looking for the first
// null slot on which we can hang our sibling
// (if there even is one; it's ok if there isn't)
while (*pp)
pp = &(*pp)->left;
// this is where we hang the sibling node
*pp = victim->left;
// the tree is fixed up and the node excised. we
// can delete it now.
delete victim;
}
// return this. remember, root may have been pointing
// to the node we deleted, and if so, it has changed
// so we need to inform the caller by return result.
return root;
}
Sans the overt comments explaining what is happening, it is a surprisingly small amount of code, especially when you consider what it is accomplishing.

Appending nodes to linked list by reading from text file almost working

Good day everyone! I have a program where it has a linked list where each node has a string name and an int for the ID's for the respective names, the append, prepend, insertafter, delete and etc. functions work fine, but I need to implement so that it reads from a text file, sample:
using this code
case 9:
{
file.open("Attendance.txt");
while (!file.eof())
{
file>>node->attendeename>>node->key;
attendance.appendAttendee(node);
}
cout << "imported\n";
}
break;
When I try to run that option, it only appends the last line in the text file as a node, console:
Here is the full program code, the rest of the program was made through collaborations with friends and online resources, I do not claim it as my own
#include <iostream>
#include <iomanip>
#include <bits/stdc++.h>
#include <sstream>
#include <fstream>
using namespace std;
//linked list node
class Node {
public:
int key;
string attendeename;
Node* next;
};
class LinkedList {
public:
Node * head;
//default constructor
LinkedList() {
head = NULL;
}
//Have head point to the node
LinkedList(Node * n) {
head = n;
}
// Checks if node exists using key value
Node * keyAlreadyExists(int k) {
Node * check = NULL;
Node * ptr = head;
while (ptr != NULL) {
if (ptr -> key == k) //checks if k already exists as a key
{
check = ptr;
}
ptr = ptr -> next;
}
return check;
}
//Append a node to the end of the list
void appendAttendee(Node * n) {
if (keyAlreadyExists(n -> key) != NULL) //first checks if a node already exists with n -> key
{
cout << "----- Node Already exists with key value : " << n -> key << ". Append another node with different Key value -----" << endl << endl;
}
else
{
if (head == NULL) //checks if list is empty
{
head = n; //the node becomes the head of the list
cout << "----- Node Has Been Appended -----" << endl << endl;
}
else
{
Node * ptr = head;
while (ptr -> next != NULL) //traverses to the end of the list
{
ptr = ptr -> next;
}
ptr -> next = n; // the current last node will now point to the passed node
cout << "----- Node Has Been Appended -----" << endl << endl;
}
}
}
// add node to the start of the list
void prependAttendee(Node * n) {
if (keyAlreadyExists(n -> key) != NULL) //first checks if a node already exists with n -> key
{
cout << "----- A Node Already exists with key value : " << n -> key << ". Append another node with different Key value -----" << endl;
}
else
{
n -> next = head; //makes node n point to the address of head
head = n;
cout << "----- Node Has Been Prepended -----" << endl << endl;
}
}
// insert a node after a specific node in the list
void insertAttendee(int k, Node * n) {
if (head == NULL) //checks if their is already a node in the list
{
cout << "----- Attendance list is still empty, can't add after key-----" << endl << endl;
} else {
Node * ptr = keyAlreadyExists(k); //checks if the int k that is passed does exist inside the list
if (ptr == NULL)
{
cout << "----- No node exists with key value: " << k << " -----" << endl << endl;
}
else
{
if (keyAlreadyExists(n -> key) != NULL) //checks if the key in the new node to be added, already exists in the list
{
cout << "-----A Node Already exists with key value : " << n -> key << ". Append another node with different Key value -----" << endl << endl;
}
else
{
n -> next = ptr -> next; //makes the newly added node point to the node that the previous node was pointing to
ptr -> next = n; //links the node that has the chosen key point to the new node
cout << "----- Node Has Been Inserted -----" << endl << endl;
}
}
}
}
// Delete a node that has the key int k
void deleteAttendee(int k) {
if (head == NULL) //checks if their is already a node in the list
{
cout << "----- Attendance list already empty. Cannot delete anymore -----" << endl << endl;
} else if (head != NULL) {
//checks if int k belongs to the key of head node
if (head -> key == k) {
head = head -> next; //makes head pointer point to the node after the head node
cout << "----- Attendee with key ID " << k << " deleted -----" << endl << endl;
} else {
Node * temp = NULL;
Node * prevptr = head;
Node * currentptr = head -> next;
while (currentptr != NULL) {
//checks if the key of currenptr is int k
if (currentptr -> key == k) {
temp = currentptr;
//gets rid of the node of currentpr
currentptr = NULL;
} else {
//moves on to the next node
prevptr = prevptr -> next;
currentptr = currentptr -> next;
}
}
//checks if a node has been deleted
if (temp != NULL) {
//makes the previous pointer point to the node after the deleted node
prevptr -> next = temp -> next;
cout << "----- Attendee with key ID " << k << " deleted -----" << endl << endl;
} else {
cout << "----- Attendee doesn't exist with key ID " << k << " -----" << endl << endl;
}
}
}
}
// update the info of a node with a specific key
void updateAttendeeInfo(int k, string name) {
//checks if a node with key int k exists
Node * ptr = keyAlreadyExists(k);
if (ptr != NULL) {
//updates the data of the node
ptr -> attendeename = name;
cout << "----- Information Updated Successfully -----" << endl << endl;
}
//output if no node contains the key int k
else {
cout << "----- No Attendee has this key ID " << k << " -----" << endl << endl;
}
}
// function to print the entire linked list
void printAttendanceList() {
//checks if the linked list contains any nodes
if (head == NULL)
{
cout << "----- No attendees recorded in list -----";
}
else
{
cout << endl << "----- List of Attendees -----" << endl;
Node * temp = head;
//to print the key and data of every node in the list
while (temp != NULL)
{
cout << "Name: " << temp -> attendeename << setw(7) << "ID: " << temp -> key;
temp = temp -> next;
cout << endl;
}
}
cout << endl << endl;
}
//function to output the entire linked list to text file
void backupAttendanceList()
{
ofstream file("Attendance.txt");
Node * temp = head;
//to print the key and data of every node in the list
while (temp != NULL)
{
file << temp -> attendeename << setw(7) << temp -> key;
temp = temp -> next;
file << endl;
}
cout << "----- Attendance list backed up successfully -----" << endl << endl;
}
} ;
int main() {
LinkedList attendance;
int choice, id, nodekey;
fstream file;
string name;
//menu screen
do {
//new node;
Node * node = new Node();
cout << "Welcome to the event! Please select option to do from the registration menu:" << endl << endl;
cout << "1 - Add attendance" << endl;
cout << "2 - Insert attendance on front of list" << endl;
cout << "3 - Insert attendance after certain key ID" << endl;
cout << "4 - Delete attendance by key ID" << endl;
cout << "5 - Update attendance details by key ID" << endl;
cout << "6 - Print list of attendees" << endl;
cout << "7 - Clear screen" << endl;
cout << "8 - Backup to text file" << endl;
cout << "9 - Import from text file" << endl;
cout << "10 - Exit Program" << endl << endl;
cout << "Your Choice: "; cin >> choice;
cout << endl;
switch (choice) {
//add attendance
case 1:
cout << "Add your attendance details. Please enter the following:" << endl
<< "Key Data: ";
cin >> id;
cin.ignore();
cout << "Name: ";
getline (cin,name);
cout << endl;
node -> key = id;
node -> attendeename = name;
attendance.appendAttendee(node);
break;
//insert attendance to top
case 2:
cout << "Insert attendance from top of list. Please enter the following:" << endl
<< "Key Data: ";
cin >> id;
cin.ignore();
cout << "Name: ";
getline (cin,name);
cout << endl;
node -> key = id;
node -> attendeename = name;
attendance.prependAttendee(node);
break;
//insert attendance after a certain node
case 3:
cout << "Insert attendance. After which key ID you want to be inserted? " << endl
<< "Key ID of attendee you want to insert after: ";
cin >> nodekey;
cout << "Add your attendance details. Please enter the following:" << endl
<< "Key Data: ";
cin >> id;
cin.ignore();
cout << "Name: ";
getline (cin,name);
cout << endl;
node -> key = id;
node-> attendeename = name;
attendance.insertAttendee(nodekey, node);
break;
//deletion of attendance
case 4:
cout << "Delete attendance. Please enter key ID to be deleted: ";
cin >> nodekey;
cout << endl;
attendance.deleteAttendee(nodekey);
break;
//update attendance
case 5:
cout << "Update existing attendance. Please enter the following:" << endl
<< "Key Data: ";
cin >> id;
cin.ignore();
cout << "Updated Name: ";
getline (cin,name);
cout << endl;
attendance.updateAttendeeInfo(id, name);
break;
//print recorded list
case 6:
attendance.printAttendanceList();
break;
//clears console screen
case 7:
system("cls");
break;
//creates txt file
case 8:
attendance.backupAttendanceList();
break;
case 9:
{
file.open("Attendance.txt");
while (!file.eof())
{
file>>node->attendeename>>node->key;
attendance.appendAttendee(node);
}
cout << "imported\n";
}
break;
//exits the program
case 10:
cout<< "Now closing program" <<endl;
exit(1);
default:
cout << "Invalid Option Number Entered, Enter Again:" << endl;
}
} while (choice != 10);
return 0;
}
The main problem is that you are appending the same node repeatedly.
Node* node = new Node();
...
while (!file.eof())
{
file>>node->attendeename>>node->key;
attendance.appendAttendee(node);
}
Your code should create a new node for each item in the file, like this
while (!file.eof())
{
Node* node = new Node();
file>>node->attendeename>>node->key;
attendance.appendAttendee(node);
}
I don't think I'm out of order in saying that you probably have multiple problems in this code (I can see one other immediately). But I'll leave you to find those out.

Write a recursive algorithm to remove elements from a linked list. Write a recursive algorithm to add elements into a linked list

I'm having some difficulties with writing adding and removing function.
Here's some code for displaying the list, searching and removing the list.
I know how to implement it iteratively, but with recursion, I have some problems.
#include <iostream>
#include <string>
using namespace std;
struct AddressBook
{
string name;
string surname;
long long phone;
AddressBook* next;
};
void delPerson(AddressBook*& head)
{
if (head == NULL)
{
cout << "There are no persons in my book\n";
}
else
{
string pName;
cout << "Enter name of person: ";
getline(cin, pName);
AddressBook* temp = head;
AddressBook* curr = NULL;
while (temp != NULL)
{
if (temp->name == pName)
{
break;
}
else
{
curr = temp;
temp = temp->next;
}
}
if (temp == NULL)
{
cout << "There are no person with this name\n";
}
else
{
if (temp == head)
{
head = head->next;
delete temp;
}
else
{
curr->next = temp->next;
delete temp;
}
cout << pName << " was deleted from the book\n";
}
}
}
void display(AddressBook* head)
{
if (head == NULL)
{
cout << "My book is empty\n";
}
else
{
AddressBook* temp = head;
while (temp != NULL)
{
cout << endl;
cout << "Name: " << temp->name << endl;
cout << "Surname: " << temp->surname << endl;
cout << "Phone: " << temp->phone << endl;
temp = temp->next;
}
}
}
void search(AddressBook* head)
{
if (head == NULL)
{
cout << "My book is empty\n";
}
else
{
cin.get();
string pName;
cout << "Enter name of person: ";
getline(cin, pName);
AddressBook* temp = head;
while (temp != NULL)
{
if (temp->name == pName)
{
cout << temp->name << " is found\n\n";
cout << "Name: " << temp->name << endl;
cout << "Surname: " << temp->surname << endl;
cout << "Phone: " << temp->phone << endl;
break;
}
else
{
temp = temp->next;
}
}
if (temp == NULL)
{
cout << pName << " isn't found in my book\n";
}
}
}
void delMemory(AddressBook* head)
{
while (head != NULL)
{
AddressBook* temp = head;
head = head->next;
delete temp;
}
}
void addPerson(AddressBook*& head)
{
string pName;
string sName;
long long pPhone = 0;
while (true)
{
cin.ignore();
cout << endl;
cout << "Enter the name(press '0' to end): ";
getline(cin, pName);
if (pName == "0")break;
cout << "Enter surname: ";
getline(cin, sName);
cout << "Enter phone: ";
cin >> pPhone;
AddressBook* bleah = new AddressBook;
bleah->name = pName;
bleah->surname = sName;
bleah->phone = pPhone;
bleah->next = NULL;
if (head == NULL)
{
head = bleah;
}
else
{
AddressBook* temp = head;
while (temp->next != NULL)
{
temp = temp->next;
}
temp->next = bleah;
}
}
}
int main()
{
cout << "=============== My Address Book ===============\n\n";
cout << "1. To add person\n";
cout << "2. To display all\n";
cout << "3. To delete person\n";
cout << "4. To search person\n";
cout << "5. Exit\n";
AddressBook* head = NULL;
int choice = 0;
while (true)
{
cin >> choice;
switch (choice)
{
case 1: addPerson(head);
break;
case 2: display(head);
break;
case 3: cin.get();
delPerson(head);
break;
case 4: search(head);
break;
case 5: return 0;
default: return 0;
}
cout << "=============== My Address Book ===============\n\n";
cout << "1. To add person\n";
cout << "2. To display all\n";
cout << "3. To delete person\n";
cout << "4. To search person\n";
cout << "5. Exit\n";
cout << endl;
}
delMemory(head);
return 0;
}
And this is recursive solution, but I have troubles implementing add and removing functions
#include <iostream>
#include <string>
using namespace std;
struct AddressBook
{
string name;
string surname;
long long phone;
AddressBook* next;
};
AddressBook* delPerson(AddressBook*& head)
{
}
AddressBook* display(AddressBook* head)
{
if (head!= NULL)
{
cout << endl;
cout << "Name: " << head->name << endl;
cout << "Surname: " << head->surname << endl;
cout << "Phone: " << head->phone << endl;
return display(head->next);
}
return head;
}
AddressBook* search(AddressBook* head, string pName)
{
if (head == NULL)
{
cout << pName << " isn't found in my book\n";
return head;
}
if (head->name == pName)
{
cout << head->name << " is found\n\n";
cout << "Name: " << head->name << endl;
cout << "Surname: " << head->surname << endl;
cout << "Phone: " << head->phone << endl;
return head;
}
else
{
return search(head->next, pName);
}
}
void delMemory(AddressBook* head)
{
if (head != NULL)
{
delMemory(head->next);
}
delete head;
}
AddressBook* allMem(AddressBook*& head)
{
}
int main()
{
cout << "=============== My Address Book ===============\n\n";
cout << "1. To add person\n";
cout << "2. To display all\n";
cout << "3. To delete person\n";
cout << "4. To search person\n";
cout << "5. Exit\n";
AddressBook* head = NULL;
string pName;
int choice = 0;
while (true)
{
cin >> choice;
switch (choice)
{
case 1: allMem(head);
break;
case 2: display(head);
break;
case 3: cin.get();
delPerson(head);
break;
case 4: cin.get();
cout << "Enter name of person: ";
getline(cin, pName);
search(head, pName);
break;
case 5: return 0;
default: return 0;
}
cout << "=============== My Address Book ===============\n\n";
cout << "1. To add person\n";
cout << "2. To display all\n";
cout << "3. To delete person\n";
cout << "4. To search person\n";
cout << "5. Exit\n";
cout << endl;
}
delMemory(head);
return 0;
}
What's already posted misses a huge portion of the problem: Asking for user input in a recursive function just leads to pain. Either the user input is asked for in every iteration or additional control information needs to be passed to to tell the function to NOT ask for user input. Either is bad planning.
Instead insert another function or two. This is beneficial from a software engineering standpoint: A function should do the absolute minimum to do one job. Functions that do only one thing are very easy to comprehend, very easy to debug, and tend to be very short.
So we need a function to get an AddressBook from the user:
AddressBook*createAddressBook()
{
AddressBook* bleah = new AddressBook; // terrible name, by the way
// since we got the bleah first, we can directly assign to it. No need for
// extra temporary variables.
cout << "Enter the name: ";
getline(cin, bleah->name);
cout << "Enter surname: ";
getline(cin, bleah->surname);
cout << "Enter phone: ";
cin >> bleah->phone; // bad idea to store phone number as a number.
// For example a number can't record preceding zeros
bleah->next = NULL;
return bleah;
}
This is a simple stupid function that does nothing but make an AddressBook. To be honest, this should be an AddressBook constructor, but we can save that for a future question. Note also that there is none of the exit on 0 nonsense. This function makes an AddressBook. Period. If you don't want an AddressBook, you don't call this function. Let the menu handle exiting.
Next we need a function to find where the AddressBoook will be added. It looks like this is always the end of the list, so
AddressBook*& findEnd(AddressBook *& head)
{
if (head != NULL)
{
return findend(head->next); // keep looking for the end
}
return head; // return the end.
}
Again, a simple, stupid function that does nothing but find the last next in the list. Note you get a reference to a pointer to an AddressBook. This allows you to happily return a next that points to NULL and replace the NULL with the new AddressBook
Which brings us back to addPerson
AddressBook* addPerson(AddressBook*& head)
{
findEnd(head) = createAddressBook();
return head;
}
Simple, stupid function that calls two other simple, stupid functions and adds a person to the list.
Apply a similar process to delPerson.
Note: I haven't run any of this. Could be a typo or two in there.
Here's a really simple example of how you can use a add to a linked list using recursion. You can apply this technique to your example above.
struct node{
int i;
node* next;
};
void add(node* cur, int i){
if(cur->next == nullptr){
node* n = new node;
n->i = i;
cur->next = n;
}
else
add(cur->next, i);
}
You simply check to see if the next node is null. If it is, you've reached the end of your list and you can add your new node there. If not, call the function recursively, providing the current next node.
Try this:
typedef struct Nodetype {
int key;
struct Node * next;
} Node;
Node * newNode(int data){
Node *temp = (Node*)malloc(sizeof(Node));
temp->key = data;
temp->next = NULL;
return temp;
}
Node* add(Node * head, int val){
if(!head)
return newNode(val);
head->next = add(head->next, val);
return head;
}
Node * delete(Node *head, int val){
if(!head)
return NULL;
Node * temp;
if(head->key == val){
temp = head;
head = head->next;
free(temp);
}
else{
head->next = delete(head->next, val);
}
return head;
}
You can change your code as per your need. I have assumed everything as integer.

Basic C++ Linked list nodes & Pointer Probs

I've been having trouble trying to retrieve data from the first node in my linked list for quite some time now. Forgive me, but I am still new to C++ and especially pointers and linked lists.
Here is how I am reading the data from my text file (working fine so far)
void readFile(ifstream& budgetFile, budgetItem *newNode, int& counter, budgetItem *temp, budgetItem *header)
{
char pauseChar;
int ctype;
string cname;
double camount;
char cleared;
itemPtr listTop = NULL;
while (!budgetFile.eof())
{
//newNode = new budgetItem;
budgetFile >> ctype >> cname >> camount >> cleared;
newNode->theType = ctype;
cout << newNode->theType << endl;
//cout << ctype << endl;
newNode->name = cname;
cout << newNode->name << endl;
newNode->amount = camount;
cout << newNode->amount << endl;
if (cleared == 'Y') {
newNode->cleared = true;
}
else{
newNode->cleared = false;
}
newNode->next = listTop;
listTop = newNode;
if (counter == 0)
{
header = newNode;
}
counter++;
}
return;
}
And here is how I am trying to retrieve the data starting from the first node. It doesn't work at all. Any help on this would be appreciated.
void showBudget (budgetItem *newNode, budgetItem *temp, budgetItem *header)
{
double incomeTotal;
double expenseTotal;
double differenceTotal;
//itemPtr *newlist;
//newNode = header;
itemPtr listTop;
budgetItem *here = listTop;
do {
cout << "INCOME:" << endl;
cout << " Item Amount Cleared" << endl;
cout << " ---------------- ------- -------" << endl;
if (newNode == NULL)
{
cout << "List is empty." << endl;
}
else
{
if (newNode->theType != 0)
{
cout << " " << newNode->name << setw(23) << fixed << setprecision(2) << newNode->amount << " ";
if (newNode->cleared == true) {
cout << "no" << endl;
}
else{
cout << "yes" << endl;
}
}
else{
cout << endl;
}
}
newNode = newNode->next;
} while (newNode != NULL);
cout << "End of List." << endl;
return;
}
// ...
counter++;
// create next node here:
newNode = new budgetItem;
}
For each new element in the list we need to allocate new object in memory. You were using the same object again and again.

C++: Binary Tree Remove Root Node

I have a program that allows a user to add and delete (amongst other things) an account to a binary search tree. I have tested/debugged this code and have found the area causing the issue, I'm just not quite sure how to fix it. I can add accounts fine, and I can remove all but the root node without error. Here is my function:
if((current->llink==NULL && current->rlink != NULL) || (current->llink != NULL && current->rlink==NULL)){
if(current->llink==NULL && current->rlink != NULL){
if(trailcurrent->llink==current){
trailcurrent->llink=current->rlink;
delete current;
current=NULL;
cout << "Account #:" << acctNum << " has been removed from the list." << endl;
}
else{
trailcurrent->rlink=current->rlink;
delete current;
current=NULL;
cout << "Account #:" << acctNum << " has been removed from the list." << endl;
}
}
else{
if(trailcurrent->llink==current){
trailcurrent->llink=current->llink;
delete current;
current=NULL;
cout << "Account #:" << acctNum << " has been removed from the list." << endl;
}
else{
trailcurrent->rlink=current->llink;
delete current;
current=NULL;
cout << "Account #:" << acctNum << " has been removed from the list." << endl;
}
}
return;
}
if(current->llink==NULL && current->rlink==NULL){
if(trailcurrent->llink==current) // This 'if' statement crashes the program with a read violation when deleting the root.
trailcurrent->llink=NULL;
else
trailcurrent->rlink=NULL;
delete current;
cout << "Account #:" << acctNum << " has been removed from the list." << endl;
return;
}
if(current->llink != NULL && current->rlink != NULL){
nodeType<accountType>* check=current->rlink;
if((current->llink==NULL)&&(current->rlink==NULL)){
current=check;
delete check;
current->rlink=NULL;
cout << "Account #:" << acctNum << " has been removed from the list." << endl;
}
else{
if((current->rlink)->llink!=NULL){
nodeType<accountType>* leftCurrent;
nodeType<accountType>* leftTrailCurrent;
leftTrailCurrent=current->rlink;
leftCurrent=(current->rlink)->llink;
while(leftCurrent->llink != NULL){
leftTrailCurrent=leftCurrent;
leftCurrent=leftCurrent->llink;
}
current->info=leftCurrent->info;
delete leftCurrent;
leftTrailCurrent->llink=NULL;
cout << "Account #:" << acctNum << " has been removed from the list." << endl;
}
else{
nodeType<accountType>* temp=current->rlink;
current->info=temp->info;
current->rlink=temp->rlink;
delete temp;
cout << "Account #:" << acctNum << " has been removed from the list." << endl;
}
}
return;
}
}
With the line that is causing me issues, do I have to have an 'if' statement before it, where trailcurrent == NULL;? If so, inside of that 'if' statement would I do something similar to
if(current->rlink>current->llink){}