Bubble sort в связанном списке. Как мне сделать сортировку по имени исполнителя? - PullRequest
0 голосов
/ 14 января 2019

Я хочу отсортировать результат по имени исполнителя, но он не работает. Я получаю AttributeError: 'str' object has no attribute 'artistName' ошибку.

Вот мой связанный список. Я добавляю музыку с идентификатором музыки, именем музыки и именем исполнителя, и связанный список распечатывает их. Я хочу отсортировать связанный список по имени исполнителя в алфавитном порядке, но мой код не работает.

Может ли кто-нибудь помочь мне исправить пузырьковую сортировку sortByArtistError(), потому что я думаю, что теперь мой код для чисел, но как мне сделать так, чтобы он располагался по алфавиту и, в частности, по имени исполнителя?

Ответы [ 2 ]

0 голосов
/ 14 января 2019

Ваш код сбивает с толку, потому что вы пытаетесь использовать имя 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
0 голосов
/ 14 января 2019

У меня недостаточно репутации, чтобы сделать простой комментарий, но зацените этот ответ . Вам следует реализовать один из алгоритмов сортировки для вашего связанного списка, в приведенном выше связанном ответе вы можете увидеть реализацию сортировки слиянием. Конечно, используйте имя художника для сравнения элементов.

Редактировать: и вот сортировка вставки

...