Условия должны быть point1 < point2
, а не pointX != pivot
. Разделение на левый и правый должно быть в том месте, где встречаются точки 1 и 2.
Обратите внимание, что в qsort важная часть сводки - это ее значение, а не индекс. Вы можете выбрать значение любого элемента из dataset
в качестве оси. Когда разделение будет выполнено, элементы слева от pivot2
будут меньше или равны значению сводки, а элементы справа от pivot1
будут выше или равны значению сводки.
Вы можете настроить pivot1
и pivot2
перед рекурсивным вызовом, чтобы массив left
содержал только элементы, меньшие, чем сводка, массив middle
содержал элементы со значением сводки иМассив right
содержит элементы, превышающие значение пивота. Это небольшая оптимизация. В результате получается left + middle + right
. Это особенно полезно, когда dataset
имеет дублированные элементы.
Эти изменения сделают ваш алгоритм правильным, но не оптимальным. Проблема заключается в том, что алгоритм создает копии частей исходного списка, который требует O(n^2)
дополнительного пространства, что составляет (n-1)*(n-2)/2
в худшем случае, когда он выбирает самое высокое или самое низкое значение в качестве сводной. Таким образом, вместо сортировки полных списков, алгоритм должен быть изменен для сортировки части списка на месте. Его интерфейс должен быть изменен на:
def qsort( a, left, right ):
, а рекурсивные вызовы должны быть:
qsort( a, left, pivot2 )
qsort( a, pivot1, right )
Другая оптимизация заключается в сокращении количества рекурсивных вызовов, поскольку они недешевы. Когда размер входного списка падает ниже определенного небольшого значения (например, 8), список можно отсортировать с помощью более простого алгоритма сортировки O(n^2)
, такого как Простая вставка, Простой выбор, Пузырьковая сортировка или аналогичного.