1

All my other functions of my doubly linked list which consist of Account class and Node class are all working except this last function.

The function bool deleteAcc(string name) will take as it’s argument, the string name (that the user inputs) and returns a bool result. It will then find the name in the list and delete the corresponding Account (and Node) from the list, then return True. If the Account was not in the list, it will return False.

This is my code as shown below:

#include <iostream>
#include "Account.h"
#include <string>
#include "Node.h"
using namespace std;

bool deleteAcc(const string name1);

int main(){

    string name;
    int k;
    cout << "How many accounts do you want to enter? ";
    cin >> k;

    Node* head = NULL;
    //Node* tail = NULL;

    for (int i = 0; i < k; i++) {
        string name;
        double balance;

        cout << "Enter account name: ";
        cin >> name;

        cout << "Enter account balance: ";
        cin >> balance;
    
        Account account(name, balance);

        Node* newNode = new Node(account);

        if (head == NULL) {
            // The list is empty, so set both head and tail to the       
            // new node
            head = newNode;
            // tail = newNode;
        } else {
            // The list is not empty, so add the new node to the  
            // tail
            newNode->setNext(head);
            //newNode->setPrevious(head); // Update previous pointer 
            // of newNode to point to the previous last node (i.e.,   
            // tail)
            head = newNode;
        }
    }

    // Print the list
    cout << "Account balances:" << endl;
    cout << endl;

    Node* currentNode = head;

    while (currentNode != NULL) {
        cout << currentNode->getData() << endl;
        currentNode = currentNode->getNext();
    }

    cout << "Enter the account name you want to delete: ";
    cin >> name;
    deleteAcc(name);



    // Deallocate memory
    currentNode = head;

    while (currentNode != NULL) {
        Node* nextNode = currentNode->getNext();
        delete currentNode;
        currentNode = nextNode;
    }

    return 0;
}

bool deleteAcc(const string name1)
{
    Node* currentNode = head;
    Node* previousNode = NULL;

    while (currentNode != NULL){
        if (currentNode->getData().getName() == name1) {
            if (previousNode == NULL) {
                // The node to be deleted is the head node
                head = currentNode->getNext();
            }   
            else {
            // The node to be deleted is in the middle of the list
            previousNode->setNext(currentNode->getNext());
            }  

        delete currentNode;
        return true;
        }

        // Update the previous node and move to the next node
        previousNode = currentNode;
        currentNode = currentNode->getNext();
    }

    // The account was not found in the list
    return false;
}

The problem is that head inside the deleteAcc(name) function is outside of the scope so is it even possible to answer this question with just a single argument string inside the bool deleteAccount(string name)????

Please help. Thanks

I have tried many times to find how to solve this problem like declaring head at the top of the file before int main() like this:

Node* head = NULL; 

int main(){
    // functions and variables here
}

but it does not produce the desired result of showing an output.

2
  • Why do you define head as a global variable? What does currentNode->getData() return, and is it printable? Commented Apr 15, 2023 at 18:12
  • @trincot, because the compiler keeps complaining that head was our of scope when I used my function bool deleteAcc(const string name1) which is defined outside of the int main(). so that is why I defined it as a global variable. but I think that is why it does not produce an output. currentNode->getData() return (name, balance) as stored in Account object and yes it is printable. Commented Apr 16, 2023 at 0:12

1 Answer 1

0

In most cases, in addition to having a Node class/struct, you'd also have another class/struct to represent the doubly linked list, and that class would hold the head node, as well as any other functions relevant to the list. See this example:

class Dllist {
    private:
        Node *head;
        int size;
    public:
        bool insertAcc(const string &name1);
        bool deleteAcc(const string &name1);
        Node *findAcc(const string &name1);
        // ...
};

Then, your deleteAcc function (as well as any other function defined as part of Dllist) would have access to head.

As you've written the code now, I'm inferring from this comment that you've set up the list entirely within main: // other functions and variables written here. If that's the case, then the only way that you'd have access to head without adding an additional parameter to the deleteAcc function would be to make head a global variable, which I'd strongly discourage.

On another node, your title has the phrase "doubly linked list", but it looks like your deleteAcc function is only modifying the forward link (i.e. calling ->setNext. For the list to maintain its status as a doubly linked list, you need to make sure that both the forward and backwards links are set appropriately.

Update: I'm responding to your comment here because the formatting is better:

@fireshawdow52, I have edited my code and put all of my code in my post. Also, it is a doubly linked list but the previous question before this, tell us to reverse order the printout of the list so I came to that conclusion that tail will not be needed anymore because it is causing compilation error.

Your tail member is absolutely needed for the structure to be doubly linked. However, newNode->setPrevious(head) won't work, as that'll result in both getNext() and getPrevious() returning the same Node. You'll want head->setPrevious(newNode) after the call to newNode->setNext(head). The reason has to do with how you're constructing your list.

Consider that we want to add three Accounts, and they'll be named "Account 1", "Account 2", and "Account 3". Here is how your list will look after the addition of each account.

After adding Account 1

     head
      |
      v
|           |
| Account 1 |
|           |

After adding Account 2

     head
      |
      v
|           |      |           |
| Account 2 | ---> | Account 1 |
|           |      |           |

After adding Account 3

     head
      |
      v
|           |      |           |      |           |
| Account 3 | ---> | Account 2 | ---> | Account 1 |
|           |      |           |      |           |

Given the above, if you uncomment the line newNode->setPrevious(head), then your final list will look like this, with each node having two pointers pointing to the same node, which is not how a doubly linked list should be set up:

     head ____________     ____________________
      |   |           |    |                  |
      v   |           v    |                  v
|         | |      |       |   |      |           |
| Account 3 | ---> | Account 2 | ---> | Account 1 |
|           |      |           |      |           |

With head->setPrevious(newNode), then you ultimately get:

     head
      |
      v
|           |      |           |      |           |
| Account 3 | ---> | Account 2 | ---> | Account 1 |
|           | <--- |           | <--- |           |

This is because, for instance, when you set the next pointer for "Account 2", head is still "Account 1", and adding a previous pointer to that node is the inverse of newNode->setNext(head).

Sign up to request clarification or add additional context in comments.

1 Comment

@fireshawdow52, I have edited my code and put all of my code in my post. Also, it is a doubly linked list but the previous question before this, tell us to reverse order the printout of the list so I came to that conclusion that tail will not be needed anymore because it is causing compilation error.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.