从C中删除链表中的节点

时间:2010-05-17 10:33:06

标签: c list linked-list

我的问题是从链接列表中删除节点。

我有两个结构:

typedef struct inner_list 
{
 int count;
 char word[100];
 inner_list*next;
} inner_list;
typedef struct outer_list
{
 char word [100];
 inner_list * head;
 int count;
 outer_list * next; 
} outer_list;

我的问题是从outer_list链表中删除一个节点。例如,当用户entered aaa要删除时,delete function should find the node with outer_list->word = aaa and delete this node and reconnect the list again。我尝试了下面的代码来做到这一点。但在找到并删除后,我正在丢失列表。我不知道出了什么问题。请注意,outer_list里面还有一个inner_list链表。

void delnode(outer_list **head,char num[100])//thanks to both Nir Levy and Jeremy P.
{
    outer_list *temp, *m;
    m=temp=*head; /*FIX #1*/
    while(temp!=NULL) {
        if(strcmp(temp->word,num)==0) {
            if(temp==*head) {
                delinner(temp->head); /* FIX#2 */
    *head=temp->next;

                free(temp);
                return;
            } else {
                delinner(temp->head); /* FIX#2 */ 
    m->next=temp->next;

                free(temp);
                return;
            }
        } else {
            m=temp;
            temp= temp->next;
        }
    }
    printf(" ELEMENT %s NOT FOUND ", num);
}
void delinner(inner_list *head) { /* FIX#2 */
    inner_list *temp;
    temp=head;
    while(temp!=NULL) {
        head=temp->next;
        free(temp);
        temp=head;
    }
}

现在我的问题已经更新了。从内部列表中删除元素时,我也尝试从inner_list中删除相同的元素。

例如: - 假设aaa是outer_list链表的一个元素,让我们用outer_list * p指出它 - 这个aaa也可以在inner_list链表中。 (它可以在p-> head或另一个内部列表中。)现在,又是棘手的部分。我尝试使用outer_list删除应用相同的规则,但每当我删除inner_list的head元素时,它都会出错。 这是我试过的:

void delnode2(outer_list *up,inner_list **head,char num[100])
{
    inner_list *temp2,*temp, *m;
 outer_list *p;
 p = up;

 while(p!=NULL){m=temp=temp2=p->head; 
    while(temp!=NULL) {
        if(strcmp(temp->word,num)==0) {
            if(temp==(*head)) {
                *head=temp->next;

                free(temp);
                return;
            } else {
                m->next=temp->next;

                free(temp);
                return;
            }
        } else {
            m=temp;
            temp= temp->next;
        }
    }
 p=p->next;
 }
    printf(" ELEMENT %s NOT FOUND ", num);
}

这里我试图发送节点并检查outer_list元素的所有inner_lists并执行删除,但是当第一个元素被删除时它会崩溃。请询问进一步的信息。我可能会用非常不整洁的词语。

6 个答案:

答案 0 :(得分:2)

FIX#1(可选) - 初始化所有变量是一个好习惯。请注意,在这个特定的情况下,因为你已经处理了头部secanrio然后你应该没有问题,因为稍后将m设置为temp,但仍然是..

FIX#2 - 确保在释放节点之前完全删除内部列表。

这是代码(未经测试,抱歉)

void delnode(outer_list *head,char num[100])
{
    outer_list *temp, *m;
    m=temp=head; /*FIX #1*/
    while(temp!=NULL) {
        if(strcmp(temp->word,num)==0) {
            if(temp==head) {
                head=temp->next;
                delinner(temp->inner_list); /* FIX#2 */
                free(temp);
                return;
            } else {
                m->next=temp->next;
                delinner(temp->inner_list); /* FIX#2 */
                free(temp);
                return;
            }
        } else {
            m=temp;
            temp= temp->next;
        }
    }
    printf(" ELEMENT %s NOT FOUND ", num);
}
void delinner(inner_list *head) { /* FIX#2 */
    inner_list *temp;
    temp=head;
    while(temp!=NULL) {
        head=temp->next;
        free(temp);
        temp=head;
    }
}

答案 1 :(得分:1)

如果您最终需要删除外部列表的第一个元素,则会出现一个大问题:您永远不会传回列表的新头部。你的原始代码需要改变如下(也包括所有其他好的建议):

void delnode(outer_list **tbd,char num[100]) // pass a pointer to tbd
{
    outer_list *temp, *m;
    temp = *tbd;
    while(temp!=NULL)
    {
        if(strcmp(temp->word,num)==0)
        {
            if(temp==*tbd)
            {
                // Delete the inner list here
                *tbd=temp->next;
                free(temp);
                return;
            }
     // rest of function

你会这样称呼它:

outer_list* myList;

// lots of code including initialising and adding stuff to the list

delnode(&mylist, wordtoDelete);  // note the '&' sign

答案 2 :(得分:0)

在您取消引用它之前,

m指针未设置为任何有效地址,并且您的程序会遇到未定义的行为。

为了修复你的实现,使用两个指针 - 一个指向当前元素,另一个指向前一个指针,并在遍历列表时更新它们。你必须将零和一元的情况视为特殊情况 - 小心。

答案 3 :(得分:0)

我认为你没有释放你的inner_list。你会得到内存泄漏。

答案 4 :(得分:0)

你正在检查单词的if条件不应该是以下内容:

if(strcmp(temp->word, num)==0)

答案 5 :(得分:0)

尝试这个(仅适用于外部列表,它不会释放内部列表):

void delnode(outer_list *head,char num[100]) 
{ 
    outer_list *temp, *m. *helper; 
    temp=head; 
    while(temp!=NULL) 
    { 
        if(strcmp(temp->word,num)==0) 
        { 
            if(temp==head) 
            { 
                head=temp->next; 
                free(temp); 
                return; 
            } 
            else 
            { 
                m = temp;
                temp = temp->next;
                helper->next = temp; //link the previous item
                free(m); 
                return; 
            } 
        }
        else 
        { 
            helper = temp;
            temp= temp->next; 
        } 

    } 
    printf(" ELEMENT %s NOT FOUND ", num); 
}