Печать узла в связанном списке

Я очень новичок в кодировании, и у меня есть основной вопрос о печати узла в двусвязном списке в Python.

class Node():
    def __init__(self, key = None, prev = None, next = None):
        self.key = key
        self.prev = prev
        self.next = next

    def __str__(self):
        return ('[%s][%d][%s]' % (repr(self.prev), self.key, repr(self.next)))

Очевидно, у меня есть еще код для самого класса списка. Допустим, у меня есть двусвязный список с двумя узлами:

узел 1: ключ 21
узел 2: ключ 10
головка --> узел 1 ‹==> узел 2

Если я печатаю (node1), я получаю:

[*location of prev node*][21][*location of next node*]

который работает именно так, как я хочу.

Итак 2 вопроса:

  1. Является ли этот код «грязным» или приемлемым синтаксисом для метода str?

  2. Вместо того, чтобы печатать местоположение предыдущего и следующего узлов, как мне вместо этого напечатать имена узлов, например. [node7][82][node9]?

Надеюсь, это имеет смысл, и спасибо за любую помощь!


person greenslime    schedule 07.12.2016    source источник
comment
1. Это нормально. 2. У ваших узлов нет имен. Если вы хотите, чтобы у них были имена, вам понадобится атрибут self.name. Одно из свойств связанного списка состоит в том, что отдельные номера не знают, где они в списке, а знают только своих соседей.   -  person Patrick Haugh    schedule 07.12.2016
comment
имена узлов - по крайней мере, каждый экземпляр узла должен иметь атрибут name   -  person RomanPerekhrest    schedule 07.12.2016
comment
@PatrickHaugh спасибо за ваш ответ. Итак, как только я создал узел, он не знает своего собственного имени... Мне пришлось бы настроить атрибут self.name, как вы сказали... понятно! Я предполагаю, что это не обычная практика, поскольку на самом деле нет необходимости печатать узлы в красивом формате.   -  person greenslime    schedule 07.12.2016
comment
Обычно вы просто ссылаетесь на узлы по их содержимому. В большинстве сценариев объект узла будет содержать ключ, который является ссылкой (то есть указателем) на что-то еще в памяти. Таким образом, узел, указывающий на ячейку памяти 0xdeadbeef, будет node 0xdeadbeef   -  person Patrick Haugh    schedule 07.12.2016
comment
Если в вашем списке есть циклы, ваш repr переполнится стеком   -  person Andrea Corbellini    schedule 08.12.2016


Ответы (1)


Вместо того, чтобы создавать self.name, необходимо инициализировать каждый Node. Вы можете добавить инициализированный self.id со статическим counter, увеличивающимся при каждом создании.

Шаг 1. Добавьте статический атрибут counter и инициализируйте атрибут self.id.

counter начинается с 0 и доступно через Node.counter.

class Node():
    counter = 0
    def __init__(self, key = None, prev = None, next = None):
        Node.counter += 1
        self.id = Node.counter
        self.key = key
        self.prev = prev
        self.next = next

Шаг 2. Измените функцию __str__, чтобы получить id из prev и next.

Имя self.prev и self.next отображается только тогда, когда не None.

Восстановите имя класса с помощью self.__class__.__name__.

def __str__(self):
    sprev = repr(self.prev)
    if self.prev != None :
        sprev = '%s%d' % (self.__class__.__name__, self.prev.id)
    snext = repr(self.next)
    if self.next != None :
        snext = '%s%d' % (self.__class__.__name__, self.next.id)
    return ('[%s][%d][%s]' % (sprev, self.key, snext))

Вот некоторые примеры:

>>> node1 = Node(21)
>>> print(node1)
[None][21][None]
>>> node2 = Node(10,node1)
>>> print(node2)
[Node1][10][None]
>>> node3 = Node(11,node2,node1)
>>> print(node3)
[Node2][11][Node1]
person J. Piquard    schedule 07.12.2016