Быстрая сортировка выбирает опорным средний элемент. На вход подают уже упорядоченный список длины n. Определите время выполнения на таком входе.
Опорный из середины
Код
def quicksort(items: list[int]) -> list[int]:
if len(items) < 2:
return items
mid = len(items) // 2
pivot = items[mid]
rest = items[:mid] + items[mid + 1:]
less = [x for x in rest if x <= pivot]
greater = [x for x in rest if x > pivot]
return quicksort(less) + [pivot] + quicksort(greater)Какое время выполнения?
Ответ: O(n log n)
В упорядоченном списке средний элемент — медиана. Каждое разбиение делит список почти поровну, поэтому уровней рекурсии около log n. На каждом уровне все подсписки вместе содержат ~n элементов, и разбиение обходит их за O(n). Итого O(n log n) — это лучший случай. Будь опорным первый элемент, тот же вход дал бы худший случай: одна часть пустая, уровней n, всего O(n²).
- Подсказка 1
Какой элемент окажется опорным, если список уже упорядочен и берётся средний элемент?
- Подсказка 2
На сколько частей и какого размера делится список на каждом уровне? Сколько всего уровней и сколько работы на каждом?