Ваш код сбивает с толку, потому что вы пытаетесь использовать имя next
в разных контекстах. Как правило, не рекомендуется использовать ключевые слова в качестве имен объектов. Кроме того, вам следует поближе познакомиться с тем, как реализовать протокол итератора, используя соответствующие методы dunder. Мне кажется, что вы что-то там упустили.
Как говорится, я придумал какой-то более чистый код. Это, конечно, не оптимально, но для удобства чтения вы можете использовать его как отправную точку для дальнейших исследований.
Для класса узла я заменил ваши методы получения и установки на объект свойства. Таким образом, вы можете получить доступ к своим переменным как к атрибутам, но за кулисами вызываются соответствующие методы получения и установки. Это экономит много печатать.
class Node:
def __init__(self, newData=None, nextNode=None):
self.data = newData
self.nxt = nextNode
@property
def data(self):
return self._data
@data.setter
def data(self, newData):
self._data = newData
@property
def nxt(self):
return self._nxt
@nxt.setter
def nxt(self, newNode):
self._nxt = newNode
Это осталось нетронутым:
class Music :
def __init__(self, id, musicName, artistName):
self.id = id
self.musicName = musicName
self.artistName = artistName
#defining how the string is displayed
def __repr__(self):
#adds in and formats the id, musicName, and artistName added to the Music collection
return f'Music ID: {self.id}\nMusic Name: {self.musicName}\nArtist Name: {self.artistName}\n'
Это не так. Чтобы иметь возможность перебирать связанный список, вам нужны методы __iter__
и __next__
dunder. Впоследствии это можно использовать для функции iteritems
, которая, в свою очередь, может использоваться для отображения списка.
За запрошенную сортировку пузырей, кредит переходит к этому репозиторию github , который я просто адаптировал для использования в этом контексте. Я не проверял, является ли это самой быстрой реализацией, но она работает.
class LinkedList:
def __init__(self):
self.head = None
self.size = 0
def __iter__(self):
self.pointer = self.head
return self
def __next__(self):
if self.pointer is None:
raise StopIteration
curr, self.pointer = self.pointer, self.pointer.nxt
return curr
def get_size(self):
return self.size
def iteritems(self):
for pos, node in enumerate(self):
yield pos, node
def addMusicToFront(self, newData):
newNode = Node(newData, self.head)
self.head = newNode
self.size += 1
def displayMusic(self):
for _, node in self.iteritems():
print(node.data)
def sortByArtistName(self):
sorted = False
count = 0
while not sorted:
sorted = True
prev = self.head
curr = self.head.nxt
while curr is not None:
if prev.data.artistName > curr.data.artistName:
sorted = False
prev.data, curr.data = curr.data, prev.data
count += 1
prev = curr
curr = curr.nxt
MusicList = LinkedList()
MusicList.addMusicToFront(Music(1, "walkingdead", "beter"))
MusicList.addMusicToFront(Music(2, "pokemon", "albert"))
MusicList.addMusicToFront(Music(3, "power ranger", "dylan"))
MusicList.addMusicToFront(Music(4, "man", "carry"))
MusicList.sortByArtistName()
MusicList.displayMusic()
На моей машине (с использованием Python 3.6) это выдает следующий вывод:
Music ID: 2
Music Name: pokemon
Artist Name: albert
Music ID: 1
Music Name: walkingdead
Artist Name: beter
Music ID: 4
Music Name: man
Artist Name: carry
Music ID: 3
Music Name: power ranger
Artist Name: dylan