Дважды связанный список в Python Использование Del - PullRequest
0 голосов
/ 23 мая 2018

Я анализировал функцию двусвязного списка, которая удаляет узел.Однако я немного запутался.

def remove( self, p ) :
        tmp = p.prev
        p.prev.next = p.next
        p.prev = tmp

Почему существуют tmp = p.prev и p.prev = tmp.Какова цель этих дополнительных строк?и, наконец, почему узлы не удаляются с помощью "del"?не должно ли быть «del p» в конце кода?

Спасибо!

1 Ответ

0 голосов
/ 23 мая 2018

Во-первых, если это целая функция, то она неправильная, что, вероятно, является одной из причин, по которой у вас возникают проблемы с ее пониманием.

Чтобы удалить узел из двусвязного списка, вам необходимо выполнить следующие действия:три вещи:

  1. Сделайте так, чтобы предыдущий узел указывал вперед на следующий узел, вместо узла p.
  2. Сделайте следующий узел указанным назад на предыдущий узел вместотекущий.
  3. Удалить текущий узел.

Поскольку в Python выполняется сборка мусора, 1 шаг 3 выполняется автоматически. 2

И шаг 1 позаботился о p.prev.next = p.next.

Но шаг 2 нигде не происходит.p.next.prev все еще указывает на p вместо p.prev.Это означает, что если вы идете по списку вперед, p не будет его частью, но если вы идете назад, он будет .Так что p на самом деле не удаляется.

Между тем, tmp = p.prev, за которым следует p.prev = tmp, не делает ничего полезного. 3 И что бы это ни было , пытаясь , чтобы сделать, вам почти никогда не нужно tmp, как это в Python;вы можете поменять значения с помощью x, y = y, x вместо tmp = x; x = y; y = tmp.


Итак, что вы на самом деле хотите здесь:

def remove(self, p):
    p.prev.next = p.next
    p.next.prev = p.prev

1.CPython, интерпретатор ссылок для Python, который вы, вероятно, используете, выполняет сборку мусора посредством автоматического подсчета ссылок с использованием прерывателя цикла, который иногда запускается.Является ли это «реальной» сборкой мусора или нет - хороший аргумент священной войны, но здесь это не имеет значения.

2.Вам просто нужно удалить все ссылки на объект, и он становится мусором и очищается автоматически.Итак, вам нужно удалить ссылки со следующего и предыдущего узлов на p, что вы уже делаете.И вам нужно отпустить p, но вам не нужно del p - это локальная переменная;он уходит, когда вы возвращаетесь из функции.После этого до звонящего remove;если они не сохраняют никаких ссылок на узел, узел является мусором.

3. может сделать что-то полезное, если мы временно назначим другое значение для p.prev и захотим восстановить его в конце функции.Но этого не происходит, и я не думаю, что тот, кто написал этот код, имел в виду нечто подобное;Я думаю, что они пытались сделать какой-то обмен.

...