簡體   English   中英

如何在C ++中從結構數組中刪除項目?

[英]How to remove an item from a structure array in C++?

我具有以下數組結構(鏈接列表):

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

str_pair *item;

我知道要創建一個新項目,我需要使用

item = new str_pair;

但是,我需要能夠遍歷數組並刪除特定項。 我有循環部分排序。 但是,如何從結構數組中刪除項目?

您顯示的不是struct數組,而是包含數組( char類型)的struct的鏈表。


數組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[]的數組中的單個項目; 您對整個數組執行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; return語句之前根本沒有任何用處。

建議的代碼:

分兩步執行:一種功能是通過連接的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;
    }
}

只需使用std :: list。 沒有理由手動編寫這樣的結構。

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

std :: list優惠已刪除。

您可以使用普通的delete關鍵字將其刪除,但這不會移動數組的所有其他成員。 如果您想要這種行為,請看一下std :: vector或類似的東西。

正如其他人指出的那樣,這是一個鏈表,而不是數組。 要回答鏈表的問題:

要插入項目:

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;

這將在p之后插入新的str_pair

刪除項目:

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;

}

可能不在主題之列,但是為什么不使用std::list庫呢?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM