我正在做一个分配给我的特定成员函数,需要完成一个链表的工作。其中之一要求我复制一个节点,更改其名称,删除旧节点,然后将新节点重新插入列表中。我想出了这段代码
while(start != NULL)
{
if(start->id == nID)
{
start->name = newName;
holdNode = start;
removeNode(nID); //removes start from the linkedlist
addNode(holdNode->name, holdNode->id, holdNode->cost);
found = true;
break;
}
else
start = start->next;
我在xcode中获得了正确的输出,但是当我使用g ++运行它时,名称字段为空或一系列随机字符。我猜想它与指向起始节点然后删除它有关,但是我不知道为什么它会在一个地方工作而在另一个地方工作。
Xcode输出
1, testing, $9.99
g ++
1, , $9.99
非常感谢您的帮助
答案 0 :(得分:2)
您的代码未制作节点的任何副本。它仅更新找到的现有节点的name
,然后将 pointer 保存到该节点,从列表中删除该节点使刚刚保存的指针无效,然后尝试使用该无效指针来获取插入新节点时要使用的值。这就是您的代码失败的地方。
尝试以下方法:
bool changeName(int nID, string newName)
{
Product *node = head;
while (node) //while there are items in the list
{
if (node->id == nID) //if ids match
{
double price = node->price;
removeNode(nID); //remove node from the linkedlist
addNode(newName, nID, price); //insert new node
return true;
}
node = node->next; //move to next node
}
return false;
}
但是,这有点低效,因为removeNode()
可能会再次进行相同的id
搜索。链表能够迅速插入和删除节点,而无需多次遍历该列表。只需取消找到的节点与其周围节点的链接。至少,您可以像这样摆脱在removeNode()
中对changeName()
的呼叫:
bool changeName(int nID, string newName)
{
Product *node = head, *prev = NULL;
while (node) //while there are items in the list
{
if (node->id == nID) //if ids match
{
double price = node->price;
//remove node from the linkedlist
//removeNode(nID);
if (prev) prev->next = node->next;
if (node == head) head = node->next;
delete node;
//insert new node
addNode(newName, nID, price);
return true;
}
prev = node;
node = node->next; //move to next node
}
return false;
}
另一种选择是根本不破坏发现的节点,只需按原样重新定位它即可。将其与周围的节点断开链接,然后将其链接到所需新位置的节点,例如:
bool changeName(int nID, string newName)
{
Product *node = head, *prev = NULL;
while (node) //while there are items in the list
{
if (node->id == nID) //if ids match
{
//remove node from the linkedlist
if (prev) prev->next = node->next;
if (node == head) head = node->next;
//insert node in new position
Product **node2 = &head;
while ((*node2) && ((*node2)->name < newName)) {
node2 = &((*node2)->next);
}
node->name = newName;
node->next = *node2;
*node2 = node;
return true;
}
prev = node;
node = node->next; //move to next node
}
return false;
}