我的双向链表的所有其他功能,包括帐户类和节点类,除了最后一个功能外都在工作。
函数 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
}
但它不会产生显示输出的预期结果。
在大多数情况下,除了具有
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)
的反函数。