Вот способ сделать это более кратко, используя несколько «хитростей» реализации односвязных списков, о которых я знаю.
Связанный список всегда состоит по крайней мере из одного sentinel узел, который автоматически создается и сохраняется в атрибуте экземпляра self._tail
.Наличие этого имеет несколько преимуществ.
- Зная, где находится
tail
, можно быстро и легко добавлять что-либо в конец. - Список никогда не бывает пустым, так что особыйдело не нужно проверять.Хороший побочный эффект этого означает, что для итерации по элементам списка требуется только следовать
self._next
, пока он не станет сторожевым узлом - одно условное выражение.
Другой «трюк» заключается в добавленииновый последний элемент справа перед текущим сторожевым узлом - что медленно звучит в односвязном списке, потому что кажется, что требуется изменить Node
для добавляемого.Чтобы добиться такого эффекта, но при этом избегать этого, нужно просто превратить существующий сторожевой узел в то, что будет содержать новый Node
, и сделать его атрибут _next
новым сторожевым.он создает замену предыдущего, который будет использоваться повторно.
Как это помогает понять, что происходит в следующем коде:
class LinkedList:
def __init__(self):
self._tail = Node()
self._head = self._tail
def add(self, data):
""" Add an item to the end of the linked list. """
new_tail = Node()
self._tail.set_data(data) # Convert existing tail into a data node.
self._tail.set_next(new_tail)
self._tail = new_tail
print('adding:', data)
def display(self):
""" Traverse linked list and print data associated with each Node. """
print('\nLinked list contents:')
curr = self._head
while curr is not self._tail:
print(' ' + curr.get_data())
curr = curr.get_next()
class Node:
def __init__(self, data=None):
self._data = data
self._next = None
def get_data(self):
return self._data
def set_data(self, data):
self._data = data
def get_next(self):
return self._next
def set_next(self, next_node):
self._next = next_node
if __name__ == '__main__':
list1 = LinkedList()
list1.add("Sugar")
list1.add("Milk")
list1.add("Tea")
list1.add("Biscuits")
list1.display()
Вывод:
adding: Sugar
adding: Milk
adding: Tea
adding: Biscuits
Linked list contents:
Sugar
Milk
Tea
Biscuits