0

我有以下数组结构(链表):

    struct str_pair   
     {  
       char ip  [50] ;  
       char uri [50] ;  
       str_pair *next ;  
     } ;

str_pair *item;

我知道要创建一个新项目,我需要使用

item = new str_pair;

但是,我需要能够遍历数组并删除特定项目。我对循环部分进行了排序。但是如何从结构数组中删除一个项目?

4

5 回答 5

5

您显示的不是 的数组struct,而是包含数组的链表struct(类型为char)。


一个数组struct看起来像这样:

str_pair array_of_structs[10];
    // or:
str_pair* dynamically_allocated_array_of_structs = new str_pair[10];

如果你真的有这样的东西,你不需要delete从数组中单个项目。假设您已按如下方式初始化数组:

str_pair* array_of_structs = new str_pair[10];

然后使用以下命令删除整个数组(包括其所有项目):

delete[] array_of_structs;

同样,您不能在分配有;delete的数组中单个项目。您对整个阵列new[]执行 a 。delete[]


另一方面,如果您打算说“链接列表struct”,那么您通常会删除类似于以下内容的项目:

str_pair* previous_item = ...;
str_pair* item_to_delete = previous_item->next;

if (item_to_delete != 0)
{
    previous_item->next = item_to_delete->next;  // make the list "skip" one item
    delete item_to_delete;                       // and delete the skipped item
}

或者,用英文:找到要删除的项目( B )之前的项目( A),然后调整A的“下一个”指针,使B在列表中被跳过,然后删除B

您需要注意特殊情况,即当要从列表中删除的项目是第一项或最后一项时。当你想删除列表中的第一项时,上面的代码是不够的,因为没有previous_item. 在这种情况下,您需要将指向列表第一个元素的指针更改为第二个元素。


你的代码:

void deleteitem(char *uri)
{
    str_pair *itemtodelete;
    curr = head;

    while (curr->next != NULL) {
    if ((strcmp(curr->uri, uri)) == 0) {
        itemtodelete = curr;
        curr = itemtodelete->next;
        delete itemtodelete;

        curr = head;
        return;
    }

    curr = curr->next;
    }
}

这里有些事情是错误的:

  • 如果head为 null,则测试curr->next != NULL将导致段错误。(您绝不能取消引用空指针!)

  • 您从列表中删除项目的代码完全不正确。最糟糕的是,您删除了一个节点而不更改前一项的下一个指针。因此,前一个项目将引用一个不再存在的项目。

  • 一个细节:curr = head;beforereturn语句根本没有做任何有用的事情。

建议代码:

分两步完成:一个函数通过其附加的找到要删除uri的节点,一个函数删除节点。你可以将它比下面的代码更好地分开,但它应该是一个起点:

str_pair* finditemwithuri(char* uri)
{
    str_pair* current = head;
    while (current)
    {
        if (strcmp(current->uri, uri) == 0) return current;
        current = current->next;
    }
    return 0;
}

void deleteitem(char* uri)
{
    // find linked list node with that uri; abort if uri not in list
    str_pair* itemtodelete = finditemwithuri(uri);
    if (!itemtodelete) return;

    // special case: node to be deleted is the list's head
    if (itemtodelete == head)
    {
        head = itemtodelete->next;
        delete itemtodelete;
        return;
    }

    // else, iterate over list nodes
    // up to the one preceding the node to be deleted
    str_pair* current = head;
    while (current)
    {
        if (itemtodelete == current->next)
        {
            current->next = itemtodelete->next;
            delete itemtodelete;
            return;
        }
        current = current->next;
    }
}
于 2010-05-02T08:44:21.677 回答
1

只需使用 std::list。没有理由手动编写这样的构造。

http://msdn.microsoft.com/en-us/library/802d66bt(VS.80).aspx

std::list 提供删除。

于 2010-05-02T16:44:43.570 回答
0

您可以使用普通的 delete 关键字删除它,但这不会移动数组的所有其他成员。如果您想要这种行为,请查看 std::vector 或类似的东西。

于 2010-05-02T08:43:49.120 回答
0

正如其他人指出的那样,这是一个链接列表,而不是一个数组。要回答您的链接列表问题:

要插入项目:

str_pair* p = // iterate over the linked list to your insertion point
str_pair* item = new str_pair;
item->next = p->next;
p->next = item;

str_pair在 p 之后插入一个新的。

要删除项目:

str_pair* p = // iterate to just before your deletion point
str_pair* item = p->next;
p->next = p->next->next;
delete item;

这将在之后删除元素p

要使用您的代码执行此操作:

void deleteitem(char *uri)
{
    str_pair *previous = NULL;
    curr = head;

    while (curr != NULL) {
        if ((strcmp(curr->uri, uri)) == 0) {

            // modify the previous element to skip over our deleted one
            if (previous)
                previous->next = curr->next;
            else
                head = curr->next;

            // safely delete the element, now that no one points to it
            delete curr;

            curr = head;
            return;
        }

        // always remember our previous element, so we can fix its 'next' pointer
        previous = curr;
        curr = curr->next;
    }
}

您还需要一个更好的添加方法:

void additem(char *uri, char *ip)
{
    curr = head;

    // traverse the list until we're at the last item
    while (curr->next != NULL) {
        curr = curr->next;
    }

    // attach a new element to the list
    curr->next = new str_pair;

    // go to that new element
    curr = curr->next;

    // set the values of the new element
    strcpy(curr->ip, ip);
    strcpy(curr->uri, uri);
    curr->next = NULL;

    curr = head;

}
于 2010-05-02T08:54:13.423 回答
0

这可能是题外话,但你为什么不使用std::list图书馆?

于 2010-05-02T13:27:11.310 回答