Страницы

Поиск по вопросам

понедельник, 18 марта 2019 г.

Python - NameError (двунаправленный связный список)

Правильно ли я реализую двунаправленный связный список и, если да, то как исправить ошибку?
class Cell: def __init__(self, value, name, prev, next): self.value = value self.name = name self.prev = prev self.next = next
E = Cell(5, "E", D, None) D = Cell(4, "D", C, E) C = Cell(3, "C", B, D) B = Cell(2, "B", A, C) A = Cell(1, "A", None, B)
NameError: name 'D' is not defined


Ответ

Вы на правильном пути, однако если конструктор списка будет принимать и предыдущую и следующую вершины, то возникнет циклическая зависимость. Возможным решением может быть убирание prev и next из конструктора и вынос их установки в отдельный метод:
class Cell: def __init__(self, value, name): self.value = value self.name = name
def set_prev_and_next(self, prev, next): self.prev = prev self.next = next
A = Cell(1, 'A') B = Cell(2, 'B') C = Cell(3, 'C') D = Cell(4, 'D') E = Cell(5, 'E')
A.set_prev_and_next(E, B) B.set_prev_and_next(A, C) C.set_prev_and_next(B, D) D.set_prev_and_next(C, E) E.set_prev_and_next(D, A)
Однако в таком случае вам нужно будет каждый раз ручками заботиться о том, чтобы значения prev и next были согласованы. Например, если вы захотите вставить элемент в середину списка, то вам нужно будет вызвать метод set_prev_and_next у трёх элементов: вставляемого, предыдущего и следующего. Гораздо лучшим вариантом будет написать метод вроде insert_after, который будет вставлять элемент после некоторого элемента и сам обрабатывать согласованность значений prev и next. Например, так:
class Cell: def __init__(self, value, name): self.value = value self.name = name self.prev = None self.next = None
def insert_after(self, cell): if self.next is None: cell.prev = self cell.next = self self.prev = cell self.next = cell else: cell.prev = self cell.next = self.next self.next = next cell.next.prev = cell
A = Cell(1, 'A') B = Cell(2, 'B') C = Cell(3, 'C') D = Cell(4, 'D') E = Cell(5, 'E')
B.insert_after(A) C.insert_after(B) D.insert_after(C) E.insert_after(D)

Комментариев нет:

Отправить комментарий