Запись деструктора LinkedList?

Действительно ли это - допустимый деструктор LinkedList? Я - все еще вид запутанных ими.

Я хочу удостовериться, что я понимаю это правильно.

 LinkedList::~LinkedList()
 {
   ListNode *ptr;

   for (ptr = head; head; ptr = head)
   {
     head = head->next
     delete ptr;
   }
}

Таким образом в начале цикла, указатель ptr установлен содержать адрес головы, первого узла в списке. голова тогда установлена на следующий объект, который станет началом списка, как только это первое удаление происходит. ptr удален и первый узел - также. С первым повторением цикла указатель установлен направиться снова.

Вещь, которая касается меня, достигает самого последнего узла. Условие "голова"; должен проверить, что это не является пустым, но я не уверен, будет ли это работать.

Любая справка ценится.

13
задан kevin 15 February 2010 в 12:45
поделиться

4 ответа

Почему бы не сделать это намного проще - с помощью элегантного while-петли вместо того, чтобы пытаться тщательно анализировать, правильна ли эта перекомпилированная for-петля?

ListNode* current = head;
while( current != 0 ) {
    ListNode* next = current->next;
    delete current;
    current = next;
}
head = 0;
17
ответ дан 1 December 2019 в 21:11
поделиться

Вы можете запустить его через отладчик, или вы можете запустить его через этот бит программного обеспечения внутри вашего черепа - оба покажут вам, что он работает нормально. Например, давайте начнем со списка:

head(47) -> [47]single_node -> [NULL]end-of-list.

Выполнение этого списка по вашим операторам:

  • ptr = head устанавливает ptr в 47.
  • head не равно нулю. так что введите цикл.
  • head = head-> next устанавливает head в NULL.
  • delete ptr удалит single_node .
  • ptr = head устанавливает ptr в NULL.
  • head теперь имеет значение NULL (0), поэтому выйдите из цикла.

Итак, вы удалили единственную запись в списке, а head теперь имеет значение NULL. Это все, что вам нужно сделать.

Вы можете сделать то же самое с более длинным списком или пустым списком, вы обнаружите, что все в порядке (нет реальной разницы между списком из одного элемента и списком из пятидесяти элементов).

Кроме того, я не большой поклонник обращения с указателями как с логическими значениями - я бы предпочел написать это как-то вроде:

for (ptr = head; head != NULL; ptr = head)

По моему мнению, это улучшает читаемость кода, и вы действительно не жертвуете ничем. производительность (если у вас нет мертвого компилятора). Но это дело вкуса.

По поводу вашего комментария:

Меня беспокоит достижение самого последнего узла. Состояние «голова»; должен проверить, что он не равен нулю, но я не уверен, что это сработает.

Это будет работать. Нулевое значение будет рассматриваться как ложное, поэтому вы обнаружите, что никогда не разыменовываете head-> next, когда head имеет значение NULL просто потому, что вы выйдете из тела цикла до этой точки (или даже не вошли в тело, если список пуст. ).

Любое другое значение указателя будет рассматриваться как истина, и вы войдете или продолжите тело цикла.

5
ответ дан 1 December 2019 в 21:11
поделиться

Условие «голова»; должен проверить, что он не равен нулю, но я не уверен, что это сработает.

Да, «head» само по себе то же самое, что «head! = Null», но зачем использовать бессмысленные ярлыки для набора текста, если даже вы находите это запутанным? Осталось всего 6 нажатий клавиш (и генерируется идентичный машинный код), поэтому выбирайте длинную форму.

Кроме того, ваш код немного сложнее, чем необходимо, потому что вы используете конструкцию for () . Почему бы не использовать while () ? Ваш код будет намного чище.

Наконец, я понимаю, что вы делаете это в качестве обучающего упражнения, но имейте в виду, что list <> находится в стандартной библиотеке --- Связанные списки официально являются «Решенной проблемой».

3
ответ дан 1 December 2019 в 21:11
поделиться

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

for (ListNode *current = head, *next; current; current = next) {
    next = current->next;
    free(current);
}
0
ответ дан 1 December 2019 в 21:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: