что делает self.next?

Рейтинг: 0Ответов: 2Опубликовано: 03.04.2023
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 можно вызывать от любого узла, он сам найдёт конец цепочки. Хотя это тоже не есть хорошо - нет единого объекта, отвечающего за список, каждый узел списка может добавить в цепочку другой узел, начав поиск с себя. С точки зрения ООП это как-то странно выглядит, должно быть всё-таки разделение ответственности, объекты одного уровня иерархии не должны лазить в свойства друг-друга и менять их. )

▲ 0

В этом коде self.next - это атрибут экземпляра класса Node, который ссылается на следующий узел (экземпляр класса Node) в связанном списке.

В методе append, создается новый узел end с переданным значением val, затем переменной n присваивается ссылка на текущий экземпляр класса Node. Далее происходит проход по связанному списку, пока n.next не будет равно None (т.е. пока не будет достигнут конец списка). Затем новый узел end добавляется в конец списка путем установки ссылки на end в n.next. Таким образом, новый узел становится последним элементом в связанном списке.