У меня большие проблемы с пониманием связанных списков, и я был бы очень благодарен, если бы кто-нибудь объяснил мне следующее.

Element_t *pushfront(Element_t *list)
{ 
if(list==0)
return allocate();

list->prev=allocate();

list->prev->next=list;

list=list->prev;

return list;
}

Что здесь означает list->prev->next=list?

Что означает это: f->next->prev=f->prev?

Я знаю, что это всего лишь часть программного кода, но я надеюсь, что кто-нибудь сможет объяснить мне их общее значение как можно проще?

2
Ninalol 27 Ноя 2016 в 22:08

3 ответа

Лучший ответ

В списке есть узлы, которые ссылаются на предыдущий узел и на следующий узел в списке.

Функция получает первый узел списка. Итак, у этого первого узла нет предыдущего узла.

В этом заявлении

list->prev=allocate();

Предыдущий узел создается, потому что, как следует из имени функции, он помещает новый узел в начало списка.

В этом заявлении

list->prev->next=list;

Выражение list->prev дает адрес нового созданного узла. Этот созданный узел должен указывать на текущий первый узел списка. Таким образом, его элемент данных next должен содержать адрес узла list.

И это утверждение

list->prev->next=list;

Является ли это.

Можно представить себе проще, если ввести промежуточную переменную.

Например

Element_t *new_node = allocate();

list->prev = new_node;      // list->prev=allocate();
new_node->next = list;     //list->prev->next=list;
list = new_node;           //list=list->prev;

return list;

Что касается этого вопроса

Что означает это: f-> next-> prev = f-> prev?

Тогда похоже, что узел f удален из списка. Теперь его следующий узел (f->next) не будет указывать на f, но будет указывать на предыдущий узел f.

Опять же, будет более понятно, если ввести промежуточные переменные.

Element_t *previous_node_of_f = f->prev;
Element_t *next_node_of_f = f->next;

next_node_of_f->prev = previous_node_of_f;  // f->next->prev=f->prev

Если добавить еще такое утверждение

previous_node_of_f->next = next_node_of_f;

Тогда узел f будет полностью удален из списка.

       --------------------------------------------------------
       |                                              prev    ^
       |                                                      |
----------------------    ----------------------    ----------------------
| previous_node_of_f |    |         f          |    |    next_node_of_f  |    
----------------------    ----------------------    ----------------------
       |                                                     ^  
       |    next                                             | 
       -------------------------------------------------------
0
Vlad from Moscow 27 Ноя 2016 в 19:54

Вот ваш код с комментариями, которые рассказывают вам, что происходит.

Element_t *pushfront(Element_t *list)
{ 
if(list==0) // If the list is emtpy
return allocate(); /* then you simply create a new node, which 
represents your list and return it. The size of your list grew from 0 to 1.*/

list->prev=allocate(); /*If the list is not empty, you add a new node by creating it,
and then the prev pointer of the first element in the list (list->prev) 
is set to this new element, as you want it to be first.*/

list->prev->next=list; /*Then you need to set the next pointer 
to the element you just added. The new element is at list->prev, 
so by list->prev->next, you just say, that the next element of the one
 you just created is the element that was first before you added the new one*/

list=list->prev; /* Here you just set the new element as the head of the list*/

return list; /*And here you return the new list*/
}

Обратите внимание, что ваш список всегда передается просто как указатель на первый элемент, поскольку это все, что вам нужно. Затем вы можете получить доступ ко всем элементам с помощью указателя next, который устанавливается для каждого элемента в списке.

0
Honza Dejdar 27 Ноя 2016 в 19:17

Во-первых, связанные списки связаны друг с другом указателями. Они не в порядке, они распределены по памяти.

Позвольте мне ответить на ваш вопрос-1 list->prev->next=list; Здесь вы связываете предыдущий узел с текущим узлом. Этот код означает, что следующая из предыдущих связана с текущим узлом. Затем предыдущий узел теперь связан со следующим указателем, который определен в структуре. Получить вопрос-2 f->next->prev=f->prev; Я не знаю, где это определяется, но здесь вы делаете это обведенный связанный список. Последний узел связан с первым узлом этим кодом.

0
Kewin Rather 27 Ноя 2016 в 19:20