← Назад к вопросам

Какая временная сложность алгоритма сортировки?

1.2 Junior🔥 101 комментариев
#Python и инструменты

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Временная сложность алгоритмов сортировки

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

Таблица основных алгоритмов сортировки

АлгоритмBest CaseAverage CaseWorst CaseДополнительная память
Bubble SortO(n)O(n²)O(n²)O(1)
Insertion SortO(n)O(n²)O(n²)O(1)
Selection SortO(n²)O(n²)O(n²)O(1)
Merge SortO(n log n)O(n log n)O(n log n)O(n)
Quick SortO(n log n)O(n log n)O(n²)O(log n)
Heap SortO(n log n)O(n log n)O(n log n)O(1)
Counting SortO(n + k)O(n + k)O(n + k)O(k)
Radix SortO(d×n)O(d×n)O(d×n)O(n + k)

где k — диапазон значений, d — количество разрядов

Почему это важно для Product Analyst-а

Хотя основная работа PA — анализ данных и метрик, понимание сложности алгоритмов пригождается в следующих ситуациях:

1. Оптимизация аналитических скриптов

  • Если нужно обработать датасет из 1 млн строк
  • O(n²) алгоритм = 10¹² операций = может зависнуть
  • O(n log n) алгоритм = 2×10⁷ операций = обработается за секунды
  • Это различие становится критичным при работе с большими данными

2. Взаимодействие с инженерами

  • Когда обсуждаем performance инфраструктуры
  • Например: "Нам нужно отсортировать 100M событий по timestamp"
  • Инженер скажет: "Используем Merge Sort, O(n log n)"
  • Я должен понимать, что это означает: примерно 2.6 млн операций

3. SQL-запросы и индексы

  • ORDER BY в SQL часто использует Quick Sort или Merge Sort
  • Понимание сложности помогает оптимизировать запросы
  • Индексированное поле сортируется быстрее (O(n log n) вместо O(n log n) без индекса, но с меньшей константой)

4. Масштабирование

  • Если у нас есть скрипт, который работает за 1 минуту на 10K строк
  • O(n²) скрипт: на 100K строк будет работать ~100 минут
  • O(n log n) скрипт: на 100K строк будет работать ~7 минут

Детальное рассмотрение основных алгоритмов

Простые алгоритмы: O(n²)

Bubble Sort — O(n²)

def bubble_sort(arr):
    n = len(arr)
    for i in range(n):  # Внешний цикл: n итераций
        for j in range(0, n - i - 1):  # Внутренний цикл: в среднем n/2 итераций
            if arr[j] > arr[j + 1]:
                arr[j], arr[j + 1] = arr[j + 1], arr[j]
    # Общее количество операций: n × (n/2) = O(n²)

Когда использовать:

  • Только для очень маленьких массивов (< 100 элементов)
  • Или в образовательных целях
  • В реальной аналитике не используется

Insertion Sort — O(n²) в среднем, но O(n) в best case

def insertion_sort(arr):
    for i in range(1, len(arr)):
        key = arr[i]
        j = i - 1
        while j >= 0 and arr[j] > key:  # Может быть 0 итераций, может быть i
            arr[j + 1] = arr[j]
            j -= 1
        arr[j + 1] = key

Когда использовать:

  • Для уже почти отсортированных данных
  • На практике часто встроена в гибридные сортировщики (как улучшение Quick Sort на маленьких массивах)

Эффективные алгоритмы: O(n log n)

Merge Sort — O(n log n) всегда

def merge_sort(arr):
    if len(arr) <= 1:
        return arr
    
    mid = len(arr) // 2
    left = merge_sort(arr[:mid])  # Рекурсия: O(log n) уровней
    right = merge_sort(arr[mid:])  # На каждом уровне n операций
    
    return merge(left, right)  # Слияние: O(n)
    # Итого: O(n log n)

Преимущества:

  • Гарантированно O(n log n) в любом случае
  • Стабильная (сохраняет порядок равных элементов)
  • Хорошо работает с внешней памятью (диск, БД)

Недостатки:

  • Требует O(n) дополнительной памяти
  • На практике медленнее Quick Sort (из-за копирований в памяти)

Quick Sort — O(n log n) в среднем, O(n²) в worst case

def quick_sort(arr):
    if len(arr) <= 1:
        return arr
    
    pivot = arr[len(arr) // 2]
    left = [x for x in arr if x < pivot]  # Раздел за O(n)
    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)  # Рекурсия: O(log n) уровней
    # Итого: O(n log n) в среднем

Когда использует в СУБД:

  • PostgreSQL, MySQL, SQLite обычно используют варианты Quick Sort или Merge Sort
  • Это то, что лежит под капотом ORDER BY в SQL

Heap Sort — O(n log n) всегда

def heap_sort(arr):
    # 1. Построение кучи: O(n)
    # 2. Извлечение элементов из кучи: n раз × O(log n) = O(n log n)
    # Итого: O(n log n)

Преимущества:

  • O(n log n) гарантированно
  • O(1) дополнительной памяти
  • Но медленнее Quick Sort на практике (плохая локальность памяти)

Специальные алгоритмы для конкретных данных

Counting Sort — O(n + k)

def counting_sort(arr, max_val):
    count = [0] * (max_val + 1)  # O(k) памяти
    for x in arr:  # O(n)
        count[x] += 1
    result = []
    for i in range(len(count)):  # O(k)
        result.extend([i] * count[i])
    return result

Когда использовать:

  • Для целых чисел в ограниченном диапазоне
  • Пример: сортировка по grade (1-5), по рейтингу (1-10)
  • Если k мало (например, k < n), это быстрее, чем O(n log n)

Radix Sort — O(d × n)

# Сортировка по разрядам (единицы, десятки, сотни...)
# d = количество разрядов (для 1000000 это 7)
# Итого: O(7 × n) для сортировки миллионов

Когда использовать:

  • Для целых чисел или строк
  • Очень быстро на больших массивах
  • Например, сортировка 1М пользователей по ID

Практические примеры из аналитики

Сценарий 1: Загрузить данные из БД и отсортировать по дате

SELECT *
FROM events
ORDER BY created_at DESC
LIMIT 100000;
  • PostgreSQL использует Quick Sort или Merge Sort
  • Если на created_at есть индекс, сортировка практически бесплатна
  • Без индекса: O(n log n) = 1.6M операций для 100K строк

Сценарий 2: Питон-скрипт обработает 10M строк CSV

import pandas as pd

df = pd.read_csv(data.csv)  # 10M строк
df = df.sort_values(user_id)  # Merge Sort в pandas
# Время: ~5-10 сек на ноутбуке
# Если бы использовался Bubble Sort: 10¹² операций = часы работы

Сценарий 3: Аналитика рейтингов пользователей (1-5 звёзд)

# Данные: миллион пользователей, каждый имеет рейтинг 1-5
# Вариант 1: Quick Sort — O(n log n) ≈ 20M операций
# Вариант 2: Counting Sort — O(n + k) ≈ 1M операций (k=5)
# Counting Sort быстрее в 20 раз!

Практические рекомендации для Product Analyst-а

Что нужно знать:

  • Разница между O(n), O(n log n) и O(n²)
  • Merge Sort и Quick Sort как стандарты
  • Counting Sort для категориальных данных

Что применять на практике:

  • В Python: встроенный .sort() и sorted() используют Tim Sort (гибрид Quick + Insertion)
  • В pandas: .sort_values() оптимизирован
  • В SQL: индексы автоматически ускоряют ORDER BY
  • Обычно не нужно думать о реализации, но нужно понимать, почему операции быстрые или медленные

⚠️ Когда консультироваться с инженерами:

  • "Этот SQL-запрос сортирует 100M строк, это долго"
  • "Пита-скрипт обрабатывает данные за часы"
  • "Нам нужно оптимизировать скорость выгрузки"
  • В этих случаях знание о сложности алгоритмов поможет вести осознанный диалог с разработчиками

Вывод

Для Product Analyst-а понимание временной сложности не является критичным ежедневным навыком, но это фундаментальное знание помогает:

  • Оптимизировать аналитические скрипты
  • Эффективнее взаимодействовать с инженерами
  • Лучше понимать, почему определённые операции медленные или быстрые
  • Масштабировать аналитику по мере роста объёма данных

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