Код, который вы представили, не совсем точно реализует алгоритм, на который вы ссылались. Рассмотрим, в частности, этот l oop:
while (*left <= *pivot && left < pivot) {
++left;
}
Соответствующий l oop в описании алгоритма не имеет аналога критерия выхода left < pivot
l oop, и его аналог *left <= *pivot
использует строго меньше, чем (<
), а не (<=
).
Легко видеть, что прежнее несоответствие должно представлять собой ошибку реализации. Конечная отсортированная позиция точки поворота - это место, где встречаются левый и правый указатели, но это условие не позволяет левому указателю когда-либо продвигаться дальше начальной позиции точки поворота. Таким образом, если правильная позиция находится справа от начальной позиции, то функция разделения, безусловно, не может вернуть правильное значение. Требуется более вдумчивый анализ, чтобы понять, что на самом деле функция разбиения, кроме того, склонна к бесконечному циклу в этом случае, хотя я думаю, что это несколько зависит от данных.
Последнее расхождение представляет собой временную ошибку. Это может привести к переполнению конца массива в случае, если выбранное значение поворота окажется самым большим значением в массиве, но это частично основано на том факте, что условие left < pivot
является ошибочным и должно быть удалено. Вы могли бы заменить последнее на left < right
, чтобы решить эту проблему, но, хотя вы могли бы сформировать рабочую сортировку таким образом, это, вероятно, не улучшило бы детали логики c, представленные в описании алгоритма.
Обратите внимание, однако, что с вариацией <=
либо quicksortpartition()
необходимо выполнить дополнительную работу (в настоящее время не предусмотрено), чтобы гарантировать, что значение поворота заканчивается в вычисленной позиции поворота, либо для функции quicksort
требуется отказаться от своего предположения, что это произойдет. Первый более практичен, если вы хотите, чтобы ваш сорт был устойчивым.