在 C++98 的双向链表中使用函数 bool deleteAcc(const string name1) 搜索字符串输入?

问题描述 投票:0回答:1

我的双向链表的所有其他功能,包括帐户类和节点类,除了最后一个功能外都在工作。

函数 bool deleteAcc(string name) 将作为参数,字符串名称(用户输入)并返回 bool 结果。然后它将在列表中找到名称并从列表中删除相应的帐户(和节点),然后返回 True。如果该帐户不在列表中,它将返回 False。

这是我的代码,如下所示:

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

问题是 deleteAcc(name) 函数中的 head 超出了范围,所以是否可以只用 bool deleteAccount(string name) 中的一个参数字符串来回答这个问题????

请帮忙。谢谢

我已经尝试了很多次来寻找解决这个问题的方法,比如在 int main() 之前在文件顶部声明 head,如下所示:

Node* head = NULL; 

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

但它不会产生显示输出的预期结果。

search boolean doubly-linked-list c++98
1个回答
0
投票

在大多数情况下,除了具有

Node
类/结构之外,您还会有另一个类/结构来表示双向链表,并且该类将包含
head
节点以及任何其他功能与列表相关。看这个例子:

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

然后,您的

deleteAcc
函数(以及定义为
Dllist
一部分的任何其他函数)将可以访问
head
.

您现在已经编写了代码,我从这条评论中推断您已经完全在

main
中设置了列表:
// other functions and variables written here
。如果是这种情况,那么在不向
head
函数添加额外参数的情况下访问
deleteAcc
的唯一方法是使
head
成为全局变量,我强烈反对。

在另一个节点上,您的标题有短语“双向链表”,但看起来您的

deleteAcc
函数只是修改前向链接(即调用
->setNext
。为了使列表保持其作为双向链表的状态,您需要确保前向和后向链接都已正确设置。

更新: 我在这里回复您的评论,因为格式更好:

@fireshawdow52,我已经编辑了我的代码并将所有代码放在我的帖子中。此外,它是一个双向链表,但在此之前的前一个问题告诉我们对列表的打印输出进行反向排序,所以我得出的结论是不再需要尾巴,因为它会导致编译错误。

您的

tail
成员是双向链接结构所必需的。但是,
newNode->setPrevious(head)
不会起作用,因为这会导致
getNext()
getPrevious()
返回相同的
Node
。在调用
head->setPrevious(newNode)
之后,您会想要
newNode->setNext(head)
。原因与您构建列表的方式有关。

假设我们要添加三个

Account
,它们将被命名为“账户1”、“账户2”和“账户3”。这是添加每个帐户后您的列表的样子。

添加账号1后

     head
      |
      v
|           |
| Account 1 |
|           |

添加账号2后

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

添加账号3后

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

鉴于上述情况,如果您取消注释行

newNode->setPrevious(head)
,那么您的最终列表将如下所示,每个节点都有两个指向同一节点的指针,这不是双向链表的设置方式:

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

有了

head->setPrevious(newNode)
,那么你最终得到:

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

这是因为,例如,当您为“账户 2”设置

next
指针时,
head
仍然是“账户 1”,并且向该节点添加一个
previous
指针是
newNode->setNext(head)
的反函数。

© www.soinside.com 2019 - 2024. All rights reserved.