Сортировка данных в языке Python: алгоритмы и практические примеры

Раздел: Алгоритмы -> алгоритмы сортировки

Алгоритмы сортировки в Python: обзор и реализация

Как выполнить сортировку списка в Python с максимальной производительностью?

Самым эффективным решением для большинства задач является использование встроенной функции sorted() или метода list.sort(). В Python эти функции реализованы на базе алгоритма Timsort, который сочетает в себе сортировку слиянием и вставками. Его временная сложность составляет O(n log n) в худшем случае, а для почти отсортированных массивов работает за O(n).

numbers = [5, 2, 9, 1, 5, 6]
sorted_numbers = sorted(numbers)
print(sorted_numbers)  # [1, 2, 5, 5, 6, 9]

numbers.sort()
print(numbers)         # [1, 2, 5, 5, 6, 9]

алгоритмы сортировки python (алгоритмы сортировки в python)

Метод sort() изменяет исходный список, а функция sorted() возвращает новый отсортированный список, не трогая оригинал. Оба поддерживают параметры key (функция для вычисления ключа сортировки) и reverse (обратный порядок).

Типичная ошибка: попытка применить sorted() к кортежу или строке - это работает, но возвращает список. Другая ошибка: передача ключевой функции, которая возвращает нечисловое значение, не поддерживающее сравнение в Python 3 (например, None). Решение: всегда убедиться, что ключ возвращает сравнимые типы.

Варианты реализации сортировки

Как реализовать простую сортировку для небольших списков? (Пузырьковая сортировка)

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

def bubble_sort(arr):
    n = len(arr)
    for i in range(n):
        swapped = False
        for j in range(0, n - i - 1):
            if arr[j] > arr[j + 1]:
                arr[j], arr[j + 1] = arr[j + 1], arr[j]
                swapped = True
        if not swapped:
            break
    return arr

sample = [64, 34, 25, 12, 22, 11, 90]
print(bubble_sort(sample))  # [11, 12, 22, 25, 34, 64, 90]

сортировка python примеры (примеры сортировки в python)

Проблемы: высокая временная сложность O(n²), большое количество обменов. Типичная ошибка - неправильно задать границы внутреннего цикла (выход за пределы). Решение: использовать признак swapped для досрочного выхода.

Как отсортировать почти отсортированный список? (Сортировка вставками)

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

def insertion_sort(arr):
    for i in range(1, len(arr)):
        key = arr[i]
        j = i - 1
        while j >= 0 and arr[j] > key:
            arr[j + 1] = arr[j]
            j -= 1
        arr[j + 1] = key
    return arr

data = [12, 11, 13, 5, 6]
print(insertion_sort(data))  # [5, 6, 11, 12, 13]

быстрая сортировка python (реализация быстрой сортировки на python)

Ошибка: неверное условие в while (arr[j] > key), если используется >=, то теряется стабильность. Проблема: для случайных данных O(n²). Решение: использовать для малых размеров или как часть Timsort.

Как отсортировать список с минимальным количеством обменов? (Сортировка выбором)

Сортировка выбором на каждом шаге находит минимальный элемент среди оставшихся и меняет его с текущим элементом.

def selection_sort(arr):
    n = len(arr)
    for i in range(n):
        min_idx = i
        for j in range(i + 1, n):
            if arr[j] < arr[min_idx]:
                min_idx = j
        arr[i], arr[min_idx] = arr[min_idx], arr[i]
    return arr

values = [29, 10, 14, 37, 13]
print(selection_sort(values))  # [10, 13, 14, 29, 37]

сортировка выбором python (сортировка выбором в python)

Недостаток: нестабильная сортировка, O(n²) сравнений. Ошибка: не обрабатывать случай, когда min_idx равен i (лишний обмен). Решение: добавить проверку if min_idx != i.

Как реализовать быструю сортировку с произвольным выбором опорного элемента?

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

def quick_sort(arr):
    if len(arr) <= 1:
        return arr
    pivot = arr[len(arr) // 2]
    left = [x for x in arr if x < pivot]
    middle = [x for x in arr if x == pivot]
    right = [x for x in arr if x > pivot]
    return quick_sort(left) + middle + quick_sort(right)

print(quick_sort([3, 6, 8, 10, 1, 2, 1]))  # [1, 1, 2, 3, 6, 8, 10]

сортировка данных python (сортировка данных в python)

Проблемы: вырождение до O(n²) при неудачном выборе опорного (например, всегда первый). Типичная ошибка: рекурсивная глубина превышает лимит для больших списков. Решение: использовать медиану трех, рандомизацию или итеративную реализацию.

Как реализовать стабильную сортировку с гарантированной O(n log n)?

Сортировка слиянием (Merge Sort) делит массив пополам, рекурсивно сортирует каждую половину и объединяет их.

def merge_sort(arr):
    if len(arr) <= 1:
        return arr
    mid = len(arr) // 2
    left = merge_sort(arr[:mid])
    right = merge_sort(arr[mid:])
    return merge(left, right)

def merge(left, right):
    result = []
    i = j = 0
    while i < len(left) and j < len(right):
        if left[i] <= right[j]:
            result.append(left[i])
            i += 1
        else:
            result.append(right[j])
            j += 1
    result.extend(left[i:])
    result.extend(right[j:])
    return result

data = [38, 27, 43, 3, 9, 82, 10]
print(merge_sort(data))  # [3, 9, 10, 27, 38, 43, 82]

Проблема: дополнительная память O(n). Ошибка: неправильное слияние (забыть добавить остатки). Решение: тщательно следить за индексами.

Как отсортировать целые числа за линейное время? (Сортировка подсчетом)

Сортировка подсчетом (Counting Sort) работает для целых чисел в известном диапазоне. Создается массив счетчиков, затем восстанавливается отсортированная последовательность.

def counting_sort(arr, max_val):
    count = [0] * (max_val + 1)
    for num in arr:
        count[num] += 1
    result = []
    for num, cnt in enumerate(count):
        result.extend([num] * cnt)
    return result

nums = [4, 2, 2, 8, 3, 3, 1]
print(counting_sort(nums, 8))  # [1, 2, 2, 3, 3, 4, 8]

Ограничение: не подходит для данных с большим разбросом или отрицательными числами. Ошибка: не задана максимальная величина. Решение: автоматически находить max и min, сдвигать значения.

Расширенные примеры сортировки в Python

Сортировка списка строк по длине

Пример
words = ['python', 'java', 'c', 'javascript', 'go']
sorted_words = sorted(words, key=len)
print(sorted_words)  # ['c', 'go', 'java', 'python', 'javascript']
Результат: ['c', 'go', 'java', 'python', 'javascript']

Сортировка списка словарей по значению ключа

Пример
students = [
    {'name': 'Alice', 'grade': 88},
    {'name': 'Bob', 'grade': 75},
    {'name': 'Charlie', 'grade': 93}
]
sorted_students = sorted(students, key=lambda s: s['grade'])
print(sorted_students)
# [{'name': 'Bob', 'grade': 75}, {'name': 'Alice', 'grade': 88}, {'name': 'Charlie', 'grade': 93}]

Многоключевая сортировка

Пример
items = [('apple', 2), ('banana', 1), ('cherry', 2), ('date', 1)]
sorted_items = sorted(items, key=lambda x: (x[1], x[0]))
print(sorted_items)
# [('banana', 1), ('date', 1), ('apple', 2), ('cherry', 2)]
Результат: [('banana', 1), ('date', 1), ('apple', 2), ('cherry', 2)]

Сначала сортируется по второму элементу (число), затем по первому (строка).

Сортировка пользовательских объектов по атрибуту

Пример
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    def __repr__(self):
        return f'{self.name}({self.age})'

people = [Person('John', 30), Person('Jane', 25), Person('Dave', 30)]
sorted_people = sorted(people, key=lambda p: (p.age, p.name))
print(sorted_people)  # [Jane(25), Dave(30), John(30)]
Результат: [Jane(25), Dave(30), John(30)]

Сортировка с использованием functools.cmp_to_key (устаревший способ)

Пример
from functools import cmp_to_key

def compare(a, b):
    if a < b:
        return -1
    elif a > b:
        return 1
    else:
        return 0

nums = [3, 1, 4, 1, 5, 9, 2]
print(sorted(nums, key=cmp_to_key(compare)))  # [1, 1, 2, 3, 4, 5, 9]
Результат: [1, 1, 2, 3, 4, 5, 9]

Обратная сортировка

Пример
nums = [5, 2, 9, 1]
print(sorted(nums, reverse=True))  # [9, 5, 2, 1]

Сортировка строк в лексикографическом порядке без учета регистра

Пример
fruits = ['banana', 'Apple', 'cherry', 'date']
sorted_fruits = sorted(fruits, key=str.lower)
print(sorted_fruits)  # ['Apple', 'banana', 'cherry', 'date']
Результат: ['Apple', 'banana', 'cherry', 'date']

Сортировка списка дат

Пример
from datetime import datetime
dates = ['2023-12-25', '2024-01-01', '2023-11-15']
sorted_dates = sorted(dates, key=lambda d: datetime.strptime(d, '%Y-%m-%d'))
print(sorted_dates)  # ['2023-11-15', '2023-12-25', '2024-01-01']

Стабильность сортировки на примере кортежей

Пример
data = [(1, 'a'), (2, 'b'), (1, 'c')]
sorted_data = sorted(data, key=lambda x: x[0])
print(sorted_data)  # [(1, 'a'), (1, 'c'), (2, 'b')] - порядок (1,'a') и (1,'c') сохранен
Результат: [(1, 'a'), (1, 'c'), (2, 'b')]

Это демонстрирует, что сортировка Timsort стабильна.

алгоритмы сортировки в Python - comments

En
алгоритмы сортировки python (python)