что делает self.next?
class Node:
def __init__(self, data):
self.next = None
self.data = data
def append(self, val):
end = Node(val)
n = self
while (n.next):
n = n.next
n.next = end
оно создает указатель на какую-то переменную!?
Ответы (2 шт):
В данном примере на мой взгляд несколько нарушены принципы ООП. Класс "Узел" (Node) одновременно отвечает и за конкретный узел и за весь связный список, построенный на этих узлах. Согласно принципам SOLID так лучше не делать. Буква S в названии принципа означает "single responsibility". Класс должен отвечать только за что-то одно. За узел - так за узел. За список - так за список. А тут что получается, сначала создаётся один узел:
Node1:
data = value
next = None
Потом на узле вызывается append, тогда создаётся следующий узел и ставится после имеющегося:
Node1: Node2:
data = value1 data = value2
next -> Node2 next = None
Добавим ещё один узел:
Node1: Node2: Node3
data = value1 data = value2 data = value3
next -> Node2 next -> Node3 next = None
В общем, поле next объекта Node указывает на следующий Node в цепочке, являющейся однонаправленным списком.
Таким образом класс Node берёт на себя и функции узла в цепочке и функции однонаправленного списка узлов. Ну то есть само указание на следующий узел тут нормально, по-другому это не сделать. Но искать, куда прицепить следующий узел, а для этого проходить по цепочке узлов, должен какой-то другой объект (например, List), более высокого уровня, на мой взгляд.
Хотя с точки зрения использования применённый подход, конечно, удобен - append можно вызывать от любого узла, он сам найдёт конец цепочки. Хотя это тоже не есть хорошо - нет единого объекта, отвечающего за список, каждый узел списка может добавить в цепочку другой узел, начав поиск с себя. С точки зрения ООП это как-то странно выглядит, должно быть всё-таки разделение ответственности, объекты одного уровня иерархии не должны лазить в свойства друг-друга и менять их. )
В этом коде self.next - это атрибут экземпляра класса Node, который ссылается на следующий узел (экземпляр класса Node) в связанном списке.
В методе append, создается новый узел end с переданным значением val, затем переменной n присваивается ссылка на текущий экземпляр класса Node. Далее происходит проход по связанному списку, пока n.next не будет равно None (т.е. пока не будет достигнут конец списка). Затем новый узел end добавляется в конец списка путем установки ссылки на end в n.next. Таким образом, новый узел становится последним элементом в связанном списке.