Основной план для вашего цикла - разрешить qn2
диапазон во всех узлах очереди.При каждом вызове qn
представляет узел, предшествующий qn2
в очереди.Этот предыдущий узел необходим для правильного обновления ссылок, когда вы находите интересующие вас узлы.
Когда qn2
является первым узлом очереди, предыдущего узла нет.Таким образом, qn
должно быть None
в этом случае.
Для каждого вызова нужно подумать о двух вещах: во-первых, какую обработку сделать на узле qn2
.Возможно, он удален или не удален.
Во-вторых, как перейти к следующему узлу очереди.Другими словами, как должен выглядеть рекурсивный вызов?Вам нужно передать узел "prev" (который будет новым qn
) и текущий узел (новый qn2
).
Давайте сосредоточимся на этой второй части проблемы, на спецификерекурсивный вызов.Предположим, что qn2
не является None
, т. Е. Что есть узел, на который нужно посмотреть.Вы должны увидеть, что если qn2
удалено, то текущий qn
также будет узлом prev для следующего вызова.Если qn2
не удален, сам qn2
будет узлом prev для следующего вызова.В любом случае поле next
узла qn2
будет новым узлом для просмотра (qn2
для следующего вызова).
Если вы посмотрите на два ваших рекурсивных вызова, ни один изу них правильная форма.В частности, следующий узел, на который нужно смотреть, всегда устанавливается в хвост очереди.Это не может быть правдой.Вы не хотите сразу переходить к концу после обработки вашего первого узла.
Кроме того, если очередь не пуста, тогда q.tail
всегда будет узлом (не None
).Следовательно, цикл никогда не прекратится.