C链表-如何删除链表上的相同元素

C链表-如何删除链表上的相同元素,c,function,pointers,linked-list,function-pointers,C,Function,Pointers,Linked List,Function Pointers,有人能告诉我这个功能是如何工作的吗? 这是我的结构: 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) {

有人能告诉我这个功能是如何工作的吗? 这是我的结构:

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;
        }
    }
}

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

我没有试过,但我很乐意帮助你。让我们看一看。正如其他用户所建议的,double-typedef真的很烦人;代码一点也不清楚,理解代码的功能更为复杂。结构组合是关于键、标签和指向下一个结构的指针。函数
delete()。第二个参数是链表根指针或开始指针

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

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

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

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;
        }
    }
}
  • 将指针的值保存在p变量中

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

  • 释放p所指的正确内存

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

希望事情清楚,我是来寻求其他帮助的。

风险自负

// 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);
        }
    }
}

不要
typedef
指针。这使得很难区分什么是指针,什么是双指针。另外,在
块中添加大括号,而
块确实令人困惑。与其让我们逐行解释代码,不如告诉我们您具体不理解的内容。你有没有在调试器中甚至在纸上浏览过代码?是的,我用调试器和纸浏览过代码,我的问题是理解指针是如何工作的。我认为这不是真正的代码。不要使用单个字符作为说明符,你不能那么懒,因为你的编辑器很可能会帮助你实现自动补全。是的,这是真正的学习代码,但一开始一切都很困难。在本例中,最难的仍然是指针。
elment
?如果你想把事情弄清楚,请确保拼写正确。事实上,不是。而且你在逻辑上的更改似乎也有缺陷:如果它是第一个要删除的节点,
l
没有相应地更新,它失去了将ptr作为输入参数传递给ptr to节点的理由。因此,你是1。未说明OP,2的原始代码。没有清理原始代码以使其更易于理解(因为整个逻辑发生了变化),3。你的新逻辑有缺陷。很抱歉,我不能假设你的答案是相关的。它更好,但你仍然是:1。未说明OP,2的原始代码。不清理原始代码以使其更易于理解(随着整个逻辑的更改)