理解为什么存储在链表中的字符串不能正确打印

Understanding why a string stored in a linked list won't print properly

我正在完成一项任务,其中我需要为链表完成特定的成员函数。其中一个要求我复制一个节点,更改其名称,删除旧节点并将新节点重新插入到列表中。我想出了这个代码

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, .99

g++

1, , .99

非常感谢任何帮助

您的代码没有制作节点的任何副本。它只是更新它找到的现有节点的 name,然后将 指针 保存到该节点,从列表中删除该节点 使指针无效您刚刚保存,然后尝试使用那个无效指针 来获取要在插入新节点时使用的值。这就是您的代码失败的地方。

试试这个:

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

Live Demo

但是,这有点低效,因为 removeNode() 可能会重新进行相同的 id 搜索。 linked 列表能够快速插入和删除节点,而无需多次遍历列表。将找到的节点从其周围节点中移除link。至少,您可以像这样在 changeName() 中摆脱对 removeNode() 的调用:

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

Live Demo

另一种选择是根本不破坏找到的节点,只需按原样重新定位它。 Unlink 它从它周围的节点,然后 link 它到所需新位置的节点,例如:

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

Live Demo