У меня есть массив, в котором хранятся рекорды викторины. У меня есть цикл for, который должен заставить сортировку пузырьков проходить все записи, однако он не работает должным образом и, кажется,

Все оценки перед сортировкой выглядят так:

[(3, ), (0, ), (1, ), (0, ), (3, ), (0, ), (0, ), (3, ), (69, )]

И после того, как сортировка "завершена", они выглядят как:

[(3, ), (1, ), (0, ), (3, ), (0, ), (0, ), (3, ), (0, ), (69, )]

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

Код для этого:

        swapScores = True
        while swapScores == True and lengthHighscore >= 0:
            swapScores = False
            for counter in range(i, lengthHighscore - 2):
                if leaderboardScores[i] < leaderboardScores[i + 1]:
                    tempScore = leaderboardScores[i]
                    leaderboardScores[i] = leaderboardScores[i + 1]
                    leaderboardScores[i + 1] = tempScore
                lengthHighscore = lengthHighscore - 1
                i = i + 1
                swapScores = True

Любая помощь была бы замечательной, спасибо! Мой код, вероятно, не так эффективен, как хотелось бы, но на данный момент я действительно стремлюсь к функциональности, а не к эффективности, ха-ха :)

0
Scott Nichol 12 Июн 2021 в 20:20

2 ответа

Лучший ответ

В вашей реализации пузырьковой сортировки есть несколько проблем:

  • i не сбрасывается в 0 на итерации внешнего цикла, что означает, что при второй оценке range внутреннего цикла это пустой диапазон. Фактически, этот диапазон всегда должен начинаться с 0.

  • Этот диапазон должен доходить до lengthHighscore - 2 включительно, поэтому диапазон должен быть range(lengthHighscore - 1) вместо lengthHighscore - 2.

  • lengthHighscore не следует уменьшать во внутреннем цикле, так как это приведет к выходу из внешнего цикла после завершения внутреннего цикла. Его следует уменьшить в внешнем цикле.

Следующее не нарушает алгоритм, но все же требует исправления:

  • swapScores = True должно происходить в блоке if, иначе это не поможет сократить алгоритм.

  • counter и i будут равны, если вы исправите вышеуказанные ошибки, поэтому вы можете просто использовать i и опустить counter

  • Python имеет приятный синтаксис для обмена значениями без использования явной временной переменной

  • Внешний цикл также может быть реализован с помощью range, так что вам не нужно явно уменьшать lengthHighscore. Затем можно использовать if not swapScores для выхода из этого цикла в качестве кратчайшего пути.

Исправленный код:

for last in range(len(leaderboardScores) - 1, 0, -1):
    swapScores = False
    for i in range(last):
        if leaderboardScores[i] < leaderboardScores[i + 1]:
            leaderboardScores[i], leaderboardScores[i + 1] = leaderboardScores[i + 1], leaderboardScores[i]
            swapScores = True
    if not swapScores:
        break

Это отсортирует оценки в порядке убывания. Если вам нужен возрастающий порядок, измените условие if, чтобы использовать > вместо <.

Очевидно, что нет необходимости реализовывать собственный алгоритм сортировки, поскольку Python имеет метод sort и функцию sorted. Они сделают работу быстрее, чем любая другая реализация с использованием кода Python.

0
trincot 12 Июн 2021 в 18:40

Вы можете легко отсортировать список кортежей с помощью sorted.

leaderboardScores = [(3, ), (0, ), (1, ), (0, ), (3, ), (0, ), (0, ), (3, ), (69, )]

# sort ascending
sorted_asc_leaderboardScores = sorted(leaderboardScores, key = lambda score: score[0])

# sort descending
sorted_desc_leaderboardScores = sorted(leaderboardScores, key = lambda score: score[0], reverse=True)
0
norie 12 Июн 2021 в 17:35