Структура узла вашего списка довольно ясна. В C это будет выглядеть примерно так:
typedef struct list list;
struct list {
list *next;
void *data;
}
Однако, если ваша задача состоит в том, чтобы удалить последний узел связанного списка, эта задача неоднозначна. В отдельных связанных списках вы обычно вставляете новые узлы спереди, потому что это может быть выполнено за постоянное время. Таким образом, остается неясным, относится ли «последний узел» к узлу, который был вставлен совсем недавно (и, следовательно, является передним узлом), или относится ли он к первому вставленному узлу (и, следовательно, является последним узлом, который вы увидите, когда вы пройти через список).
В первом случае действительно легко удалить «последний» узел списка list
, потому что это передний узел: list = list->next
. Вы можете включить крайний случай пустого списка: list = list?list->next:NULL
.
Во втором случае, когда вы должны удалить узел, который был вставлен первым, это немного сложнее. Вы должны пройти через список, поддерживая указатель на текущий элемент и, кроме того, указатель на элемент перед этим. Вот некоторый код, который вам может пригодиться:
cur = list->next;
prev = list;
while (cur->next != NULL) {
prev = cur;
cur = cur->next;
}
prev->next = NULL;
free(cur->data);
free(cur);
Этот код выполняет итерацию по списку и останавливается, когда cur указывает на последний узел (единственный узел списка, чей следующий указатель указывает на NULL). Затем мы отсоединяем последний узел, устанавливая следующий указатель предыдущего элемента в NULL.
Обратите внимание, что у вас есть два особых случая:
- список изначально пуст (тут ничего не поделаешь)
- список содержит только один элемент (т. е. первый элемент является последним элементом, переключитесь на метод, описанный ранее)