如何基于字符串删除链表中的节点

时间:2014-10-11 05:15:37

标签: c pointers linked-list nodes

正如标题所暗示的那样。删除链接列表中的第一个节点就像一个魅力。这是其他dang节点!好的,这是我的代码。我想我正在删除,但我没有正确链接。

以下是结构和typedef的样子:

typedef struct List *ListP;
typedef struct Entry *EntryP;
typedef char *ListItemP;

struct List
{
    int sizeL;
    struct Entry *head;
};

struct Entry
{
    ListItemP content;
    struct Entry *next;
    int sizeL;
};

removeItemList函数在main.c中的工作方式是传递列表指针(ListP thisList)和字符串(ListItemP thisItem)。一旦传递了参数,该函数将搜索与列表中的节点相同的字符串(通过strcmp()),并在找到它时将其删除。 NewEntry初始化Entry结构并具有将字符传递给newEntry->内容的输入。无论如何,这是功能:

void removeItemList(ListP thisList, ListItemP thisItem)
{
    EntryP temp = newEntry(0x00);
    EntryP temp2 = newEntry(0x00);

    temp->next = thisList->head;
    temp2->next = thisList->head;
    if (strcmp(temp->next->content, thisItem) == 0)
    {
        thisList->head = temp->next->next;
    }
    else {
         while(temp->next != 0x00)
         {
            if(strcmp(temp->next->content,thisItem) == 0) {
                break;
            }
            temp->next = temp->next->next;
            temp->sizeL++;
         }
        if (temp->next == 0x00) {
        }
        else {
            int i = 0;
            for(i = 0; i < temp->sizeL - 1 ; i++)
            {
                temp2->next = temp2->next->next;
                printf("%s \n", temp2->content);
            }
            temp2->next = temp->next->next;
            free(temp2->next);
        }
    }
    thisList->sizeL--;
}

我认为删除节点之前的节点最终被指向null。不过,我无法弄清楚如何解决这个问题。我猜这就是我在这里的原因!非常感谢,非常感谢!

编辑:更新的代码,加上DIPLAY列表代码

更新了removeItemList()

void removeItemList(ListP thisList, ListItemP thisItem)
{
    EntryP current = newEntry(0x00);
    EntryP prev = newEntry(0x00);

    prev = 0x00;
    current = thisList->head;

    if (strcmp(current->content, thisItem) == 0)
    {
        thisList->head = current->next->next;
    }
    else {

        while (current->next != 0x00)
        {
            prev = current;
            current = current->next;
            if (strcmp(current->content, thisItem) == 0)
            {   
                prev->next = current->next;
                free(current);
            }
        }
    }
}

显示列表():

void displayList(ListP thisList)
{   
    EntryP temp = newEntry(0x00);
    temp->next = thisList->head;
    while(temp->next != 0x00)
    {
       printf("%s \n", temp->next->content);
       temp->next = temp->next->next;
    }
    free(temp);
}

如果我只是使用printf()语句,我可以很好地访问所有内容,并且节点似乎已被删除。但是,如果我尝试使用displayList()打印它们,则在删除节点之前打印节点后会出现段错误。所以好像我没有正确地连接节点。

1 个答案:

答案 0 :(得分:1)

要删除任何中间节点,请保持两个指向列表的指针,prev和cur。将prev初始化为null并将cur初始化为列表的头部。现在遍历列表,直到遇到要删除的节点。在移动到分析中的下一个节点之前,将prev重新分配给cur并将cur重新分配到cur-> next。 到达所需节点时,执行

prev->next = cur->next;
free(cur);

return;// If necessary.

整个伪代码:

prev = null;
cur = list->head;

while(cur!=null)
{
   if(//This is the node to be deleted)
   {
        prev->next = cur->next;
        free(cur);
        return;
   }

   prev = cur;
   cur = cur->next;

}
//Node not found case

现在将此方案集成到您的代码中,您应该没问题。在此之前,只需明确检查第一个节点,因为这不适合上述用例。

UPDATE :我注意到你的函数DisplayList()中有一些错误。为什么在遍历期间使用temp-&gt;进行分析?对我来说,这似乎是一种迂回的方法。只需用temp。

进行分析
void displayList(ListP thisList)
{   
    EntryP temp = thisList->head;
    while(temp!= 0x00)
    {
      printf("%s \n", temp->content);
      temp = temp->next;
    }
}

为什么在列表显示期间释放临时节点?如果您只想显示列表内容,释放节点没有任何意义。对我来说。