Рубрики
Без рубрики

Алгоритмы сортировки в Python

Мы рассмотрим 4 разных алгоритма сортировки и их реализацию в Python: Bubble S … Tagged с помощью Python, Tutorial, Algorithms, Sorting.

Мы рассмотрим 4 различных алгоритма сортировки и их реализацию в Python:

  • Пузырьковые сортировки
  • Выбор сортировки
  • Вставка сортировки
  • Quicksort

Сложность времени: O (N²)

Реализация

def bubble(lst):
    no_swaps = False
    while no_swaps == False:
        no_swaps = True
        n = 0
        for i in range(len(lst) - 1 - n):
            if lst[i] > lst[i + 1]:
                lst[i], lst[i + 1] = lst[i + 1], lst[i]              
                no_swaps = False
        n += 1

Как это работает

  1. Переходить через элементы в массиве
  2. Если в неправильном порядке есть соседние элементы, поменяйте их
  3. Если мы достигли конца массива, и в этой итерации не было никаких изменений, то массив отсортирован. Иначе повторите с шага 1.

Например, предположим, что у нас есть следующий массив:

В первом проходе, когда я , LST [0] и LST [1] Анкет Начиная с 26 <54, и мы хотим сортировать массив в порядке возрастания, мы поменяем позиции 54 и 26, чтобы 26 приходили до 54. Это продолжается до конца списка.

Обратите внимание, что самый большой элемент (93) Всегда передается до конца массива во время первой итерации. Это причина переменной n который увеличивается после каждой итерации и говорит программе исключить последний элемент после каждой итерации по (суб) массиве.

Временная сложность – O (N²), потому что она занимает n Итерации, чтобы гарантировать отсортированный массив, и каждая итерация итерации итерации над n элементы.

Сложность времени: O (N²)

Реализация

def selection(lst):
    for i in range(len(lst)):
        iMin = i
        for j in range(i + 1, len(lst)):
            if lst[j] < lst[iMin]:
                iMin = j
        lst[i], lst[iMin] = lst[iMin], lst[i]

Как это работает

  1. Переходить через элементы в массиве
  2. На каждой позиции переверните через несортированные элементы, чтобы найти минимальный элемент
  3. Обмениваться позициями этого минимального элемента и элемента в текущем положении

Например, предположим, что у нас есть следующий массив:

Когда я , минимальное значение в неортированном массиве составляет 1, в позиции j . Следовательно, элементы в положении 0 и позиции 3 заменяются.

Когда я , минимальное значение в неортированном массиве (несортированный массив равен [5, 7, 8, 9, 3] Поскольку первая позиция уже отсортирована) 3, в позиции j . Следовательно, элементы в положении 1 и 5 заменяются. Несортированный массив теперь [7, 8, 9, 5] .

Это продолжается, пока минимальное значение не будет выбрано (Отсюда и название) для всех позиций. Временная сложность – O (N²), поскольку мы должны итерации через несортированный массив n раз, один раз для каждой текущей позиции, и несортированный массив состоит из n элементы в среднем.

Сложность времени: O (N²)

Реализация

def insertion(lst):
    for i in range(1, len(lst)):
        temp = lst[i]
        j = i - 1
        while j >= 0 and temp < lst[j]:
            lst[j + 1] = lst[j]
            j -= 1
        lst[j + 1] = temp

Как это работает

  1. Переходить через элементы в массиве
  2. Для каждого элемента обращайтесь через отсортированный массив, чтобы найти подходящую позицию (где оно больше элемента прямо перед ним, и меньше элемента сразу после него)

    Например, когда я и lst [i] , Я хочу вставлять (Отсюда и имя) 31 в сортированный массив. В то время как Loop будет «скопировать» элемент в J на позицию J + 1 и уменьшить значение J , до 31> lst [j] Анкет Это происходит в J , где lst [j] Анкет С 26 <31 <54, правильная позиция для вставки 31 будет в J + Анкет

  3. Вставьте элемент в подходящую позицию. От шага 2 все элементы этой позиции и дальше «отталкиваются» вправо на одну позицию, чтобы освободить место для вставленного элемента

Например, предположим, что у нас есть следующий массив:

Когда я , нет отсортированного массива, и мы просто переходим к я Анкет Обратите внимание, что этот случай захвачен под одним из В то время как Условия выхода петли; С тех пор Дж это Ложный , while Loop не будет запущен.

Когда я , отсортированный массив состоит из [54,] и текущий элемент 26. Правильное положение для вставки 26 составляет до 54, поэтому 54 «отталкивается» вправо (теперь оно находится в положении 1), а 26 вставляется в позицию 0.

Это продолжается, пока все элементы не будут вставлено на их подходящих позициях и весь массив отсортирован. Временная сложность – O (N²), потому что мы должны итерации через отсортированный список n раз, чтобы найти подходящую позицию для всех n Элементы и сортированный список состоит из n элементы в среднем.

Сложность времени: O (n log (n))

Реализация (вне места)

def quicksort(lst):

    if len(lst) == 0:
        return lst

    else:
        pivot = lst[0]
        left = []
        right = []

        for ele in lst:

            if ele < pivot:
                left.append(ele)

            if ele > pivot:
                right.append(ele)

        return quicksort(left) + [pivot] + quicksort(right)

Реализация (на месте)

def partition(lst, start, end):

    # partition list into left (< pivot), middle (pivot) and right (> pivot), and return position of pivot

    pivot = lst[start]
    left = start + 1
    right = end

    done = False    
    while not done:        

        # find left position where element > pivot
        while left <= right and lst[left] < pivot:
            left += 1        

        # find right position where element < pivot
        while right >= left and lst[right] > pivot:
            right -= 1

        if left > right:
            # stop sorting
            done = True

        else:
            # lst[left] now < pivot, lst[right] now > pivot            
            lst[left], lst[right] = lst[right], lst[left]

    # place pivot in the correct position
    lst[start], lst[right] = lst[right], lst[start]

    return right        

def quicksort_in_place(lst, start, end):

    # sort list recursively with the help of partition()

    if start < end:

        pivot = partition(lst, start, end)    

        quicksort_in_place(lst, start, pivot - 1)        
        quicksort_in_place(lst, pivot + 1, end)

Как это работает

Это рекурсивный алгоритм. Для каждого рекурсивного вызова,

  1. Первый элемент массива воспринимается как «поворот»
  2. Разделяйте массив так, чтобы у вас было подзадач из элементов, которые меньше, чем олова, и еще один подзадачен элементов, которые больше, чем олова. Позиционируйте поворот в середине двух субаррей.
  3. Рекурсивно сортируйте оба субарри

Базовый случай: когда субрай пуст (или содержит только один элемент), он не может быть отсортирован дальше.

Алгоритм на месте

Алгоритм на месте изменяет оригинал Массив, в то время как алгоритм вне места создает и возвращает новый массив, который является отсортированной версией оригинального массива. Рекурсионная логика в значительной степени такая же, за исключением раздел () Функция может быть немного запутанной.

Функция разделения включает в себя левые и правые указатели. Левый указатель движется вправо, пока не найдет элемент, который больше, чем оловка. Правый указатель перемещается влево, пока не найдет элемент, который меньше шарнира. Эти два элемента затем заменены, потому что мы хотим, чтобы все слева было меньше, чем олова, и все справа, чтобы быть больше, чем олова.

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

Левый субаррей состоит из всего до овода, и все в этом субраре меньше, чем олова. Правильный Subarray состоит из всего после отвода, и все в этом Subarray больше, чем The Pivot.

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

Временная сложность

Работая снизу вверх, 1 × 2ʰ = не где h высота рекурсивного дерева и n размер массива. Это связано с тем, что начиная с «листа» (одноэлементный субрай), каждый слой над ним объединяет два субарра, чтобы сформировать новый массив, который в два раза превышает длину каждого отдельного субрай. Таким образом, размер субара примерно удваивается каждый раз, когда он поднимается в слое. Следовательно, h , высота рекурсивного дерева, это лог (n).

На каждом слое рекурсивного дерева, в общей сложности n Сравнения проводятся для разделения каждого субара (поскольку общее количество элементов все еще n ).

Следовательно, общая временная сложность – O (n log (n)).

Спасибо за чтение! Если у вас есть какие -либо вопросы, не стесняйтесь комментировать этот пост.

Следуйте за мной за большим количеством таких историй, как этот в будущем.

Оригинал: “https://dev.to/zeyu2001/sorting-algorithms-in-python-4eaf”