Сортировка пузырьком проходит по массиву несколько раз. На каждом этапе алгоритм сравнивает два соседних элемента и, если левый элемент больше правого — меняет их местами. Такой проход гарантирует что самое больше число будет в конце массива. Этот процесс попарного сравнения повторяется до тех пор, пока каждый элемент не будет на своем месте.
def bubble_sort(arr):
n = len(arr)
for i in range(n):
for j in range(n-i-1):
if arr[j] > arr[j+1]:
arr[j], arr[j+1] = arr[j+1], arr[j]
return arr
Оценка сложности:
- В худшем случае O(n)
- В среднем случае O(n²)
- В лучшем случае O(n²)
Основная идея — рассматривать последовательность как две части: первая включает отсортированные элементы, вторая — неотсортированные. Алгоритм находит наименьшее число из неотсортированной части и помещает его в конец отсортированной.
def selection_sort(arr):
n = len(arr)
for i in range(n-1):
min_index = i
for j in range(i+1, n):
if arr[j] < arr[min_index]:
min_index = j
if min_index != i:
arr[i], arr[min_index] = arr[min_index], arr[i]
return arr
Оценка сложности:
- В худшем случае O(n)
- В среднем случае O(n²)
- В лучшем случае O(n²)
Этот алгоритм совмещает идеи первых двух алгоритмов. Как и в сортировке выбором представляем последовательность как две части: первая включает отсортированные элменты, вторая — неотсортированные. Алгоритм сортировки вставками последовательно помещает каждый элемент из неотсортированной части на правильную позицию отсортированной части.
def insertion_sort(arr):
n = len(arr)
for i in range(1, n):
current_value = arr[i]
j = i - 1
while j >= 0:
if current_value < arr[j]:
arr[j+1] = arr[j]
arr[j] = current_value
j = j - 1
else:
break
return arr
Оценка сложности:
- В худшем случае O(N²)
- В среднем случае O(N²)
- В лучшем случае O(N²)
Рекурсивный алгоритм, который работает по следующему принципу:
- Выбрать опорный элемент из массива. Это можно сделать разными способами, в данной реализации этой будет случайный элемент.
- Сравнить все элементы с опорным и распределить их в подмассивы. Первый подмассив будет состоять из элементов, которые меньше опорного; второй — больше опорного или равные.
- Рекурсивно выполнить шаги 1 и 2, пока в подмассиве есть хотя бы 2 элемента.
import random
def quick_sort(arr):
n = len(arr)
if n <= 1:
return arr
else:
pivot = random.choice(arr)
less = [x for x in arr if x < pivot]
greater_or_equal = [x for x in arr if x >= pivot]
return quick_sort(less) + quick_sort(greater_or_equal)
Оценка сложности:
- В худшем случае O(n²)
- В среднем случае O(n * log n)
- В лучшем случае O(n * log n)
Рекурсивный алгоритм, который работает по следующему принципу:
- Разделить массив на две равные части
- Отсортировать каждую половину
- Из двух отсортированных массивов получить один (операция слияния)
def merge_sort(arr):
n = len(arr)
if n <= 1:
return arr
else:
middle = int(len(arr) / 2)
left = merge_sort(arr[:middle])
right = merge_sort(arr[middle:])
return merge(left, right)
def merge(left, right):
result = []
while len(left) > 0 and len(right) > 0:
if left[0] <= right[0]:
result.append(left[0])
left = left[1:]
else:
result.append(right[0])
right = right[1:]
if len(left) > 0:
result += left
if len(right) > 0:
result += right
return result
Оценка сложности:
- В худшем случае O(n * log n)
- В среднем случае O(n * log n)
- В лучшем случае O(n * log n)