【问题标题】:C Linked List - understending, how to delete the same element on list [closed]C链接列表-理解,如何删除列表中的相同元素[关闭]
【发布时间】:2016-01-05 23:36:25
【问题描述】:

有人能告诉我,这个功能怎么可能有效? 这是我的结构:

struct el{
    int key;
    struct el *next;
};
typedef struct el elListy;
typedef elListy *list;

这是函数:

void delete(list *l, int zm)
{
    list p, *k;
    k = l;
    while ((*k))
    {
        if ((*k)->key == zm) {
            p = *k;
            *k = (*k)->next;
            free(p);
        }
        else
        {
            k = &(*k)->n;
        }
    }
}

如果有人能说明,那就太棒了。

【问题讨论】:

  • 不要typedef指针。很难区分什么是指针,什么是双指针。另外,在while 块中添加大括号,这确实令人困惑。
  • 与其让我们逐行解释代码,不如告诉我们您具体不明白的地方。您是否在调试器中甚至在纸上浏览过代码?
  • 是的,我使用调试器和纸张浏览了代码,我的问题是了解这里的指针是如何工作的。
  • 我认为这不是真正的代码。不要使用单个字符作为说明符,你不能那么懒惰,因为你的编辑器很可能会帮助你使用它的自动完成功能。
  • 是的,这是真正的学习代码,但一开始一切都很艰难。在这个例子中,最难的仍然是指针。

标签: c function pointers linked-list function-pointers


【解决方案1】:

我没有尝试过,但我很乐意为您提供帮助。让我们来看看。正如其他用户所建议的那样,double typedef 真的很烦人;代码根本不清楚,理解这段代码的作用更复杂。结构组合是关于一个键、一个标签和一个指向下一个结构的指针。函数delete() 将他的int zm 与链表的任何节点进行比较,该函数将其作为参数。第二个参数是链表根指针,也就是起始指针。

关于功能: 换句话说,该函数正在读取链表的任何值(键)并将其与 int zm 进行比较。如果 key 不同, (*k) 将是下一个指针。此方法允许从起始节点参数读取每个节点。注意最后一行n 应该是next

如果 key 和 zm 相等,该函数使用free() 函数释放链表节点(因为链表节点通常使用 malloc 或 calloc 函数构建)并将 k 的值设置为双精度指针和 (*k),第一个指针的值,也是一个指针 - 指向下一个,以便检查下一个节点并在需要时将其删除。

特别是如果zm等于key,函数:

  • 将指针的值保存在p变量中;

  • 设置k指向下一个结构体,因为在k值上配置了while条件,可以找到2个或更多具有相同key的节点;

  • 释放p指向的正确内存;

重点关注两件事很重要: 1)设置 k 值指向下一个结构很重要,因为可以防止代码不停止到它找到的第一个值。 2) while 条件 (*k) 表示您正在检查 k 的值,它是一个指针,直到它为 NULL,这意味着结束。

希望它足够清楚,我在这里寻求其他帮助。

【讨论】:

    【解决方案2】:

    风险自负!!!

    // sory i have chaged the names, this will make it litle bit clearer
    
    typedef struct elment elment, *p_elment;
    
    typedef p_elment *list;
    
    struct elment{
        int         key;
        p_elment    next;
        p_elment    prev; // you will need it;
    };
    
    
    void delete(list *l, int zm) {
    
        p_elment    k,p;
    
        k = (p_elment) *l; // cast to avoid warnings
    
        while (k){
            p = k;
            k=k->next;
    
            if (p->key == zm) {
    
                if (*l == p) 
                      *l=p->next;
    
                if(p->prev)
                    p->prev->next = p->next;
    
                if(p->next)
                    p->next->prev = p->prev;
    
                free(p);
            }
        }
    }
    

    【讨论】:

    • elment?如果你想让事情更清楚,请确保你的拼写正确
    • 好吧,实际上没有。而且您的逻辑更改似乎也有缺陷:如果它是第一个要删除的节点,l 不会相应更新,并且它失去了将 ptr-to-ptr-to-node 作为输入参数传递的理由。
    • 所以你是1.没有说明OP的原始代码,2.没有清理原始代码以使其更容易理解(因为整个逻辑发生了变化),3.你的新逻辑有缺陷.抱歉,我不能假设您的回答是相关的
    • 更好,但你仍然是:1.没有说明OP的原始代码,2.没有清理原始代码以便更容易理解(因为整个逻辑发生了变化)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-13
    • 1970-01-01
    相关资源
    最近更新 更多