从链接列表中删除最后一个元素

时间:2019-04-30 17:06:30

标签: c pointers linked-list

对于一个项目,我需要用C语言实现的链表实现,这样我就可以删除最后一个元素。

但是,我不知道该如何实现。 想法是创建一个函数(deleteLast),该函数在列表上进行迭代,直到下一个元素的下一个为NULL(因此直到到达倒数第二个元素),然后释放对最后一个元素的引用。

但是,尝试编译时出现错误“表达式必须具有指向结构或联合的指针类型”。

#include <stdio.h>
#include <stdlib.h>

struct cell{
    int x_coord,y_coord;
    struct cell *next;
} cell;

struct cell AddToList (struct cell *list, int x,int y);
int listlength(struct cell * list);
void deleteLast(struct cell **list);

struct cell AddToList(struct cell *list,int x,int y){
    struct cell *new_cell;
    new_cell = malloc(sizeof(struct cell));
    new_cell->x_coord=x;
    new_cell->y_coord=y;
    printf("Added new coordinates %i %i",x,y);
}

int listlength(struct cell *list){
    int i=0;
    while(list->next != NULL){
        i++;
    }
    return i;
}

//takes a pointer as reference, because in C parameters are given as values
//see: https://stackoverflow.com/a/35021864
//calls should look like deleteLast( &list )
void deleteLast(struct cell **list){
    struct cell *currentcell = *list;
    while(*list->next->next != NULL){ //expression must have pointer-to-struct-or-union type
        //free list->next
    }
}

哪里出错了?

2 个答案:

答案 0 :(得分:1)

void deleteLast(struct cell **list){
    struct cell * currentcell = *list;
    while(currentcell->next->next != NULL) {
        currentcell = currentcell->next;
    }
    free(currentcell->next);
}

答案 1 :(得分:1)

自从Daniel Siegel明确要求我扩大对Andrew Pierre的回答。这是我在评论中写的。

在取消引用之前,您始终必须检查您的指针是否不是NULL,并且在释放某些内容后必须显式分配NULL,因为free不会为您这样做,而是给您留下看起来不错但没有指向任何内容的指针

void deleteLast(struct cell **list){
    //Do nothing if list is a NULL
    if (!list){
        return;
    }
    struct cell * currentcell = *list;
    //Do nothing if list is empty
    if (!currentcell){
        return;
    }
    //Check if first element is last element
    if (!currentcell->next){
        free(currentcell);
        //assign NULL to the pointer in list not to currentcell
        //since currentcell is a local variable.
        *list = NULL;
        return;
    }
    while(currentcell->next->next != NULL) {
        currentcell = currentcell->next;
    }
    free(currentcell->next);
    //explicit set last element to NULL
    currentcell->next = NULL;
}