C Linked List - недопонимание, как удалить тот же элемент в списке
Может кто-нибудь сказать мне, как это возможно, что эта функция работает? Это моя структура:
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;
}
}
}
Если кто-то может это проиллюстрировать, будет круто.
2 ответа
Я не пробовал, но я рад помочь вам. Давайте взглянем. Как полагают другие пользователи, двойной typedef действительно раздражает; код не совсем понятен, и понять, что делает этот код, сложнее. Состав структуры состоит из ключа, метки и указателя на следующую структуру. Функция delete()
сравнивает его int zm
, который принимает его в качестве аргумента, с любым узлом связанного списка. Второй аргумент - это корневой указатель связанного списка или начальный указатель.
О функции: Словом, функция читает любое значение (ключ) связанного списка и сравнивает его с int zm. Если ключ отличается, (*k) будет следующим указателем. Этот метод позволяет читать каждый узел из аргумента начального узла. Будьте осторожны в последней строке, где n
должно быть next
,
Если key и zm равны, функция освобождает узел списка с помощью free()
функция (потому что узел связанного списка обычно создается с помощью функции malloc или calloc) и устанавливает, что значение k, которое является двойным указателем, и (*k), значение первого указателя, также является указателем - указатель на следующий один, чтобы проверить следующий узел и удалить его при необходимости.
В частности, если zm равно ключу, функция:
сохраняет значение указателя в переменной p;
установить, что k указывает на следующую структуру, потому что условие while настроено на значение k, и можно найти 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);
}
}
}