Delphi имеет эту реализацию QuickSort в одном из образцов:Оптимизация или неправильная реализация QuickSort
procedure QuickSort(var A: array of Integer; iLo, iHi: Integer);
var
Lo, Hi, Mid, T: Integer;
begin
Lo := iLo;
Hi := iHi;
Mid := A[(Lo + Hi) div 2];
repeat
while A[Lo] < Mid do Inc(Lo);
while A[Hi] > Mid do Dec(Hi);
if Lo <= Hi then
begin
VisualSwap(A[Lo], A[Hi], Lo, Hi); // just for visual
T := A[Lo];
A[Lo] := A[Hi];
A[Hi] := T;
Inc(Lo);
Dec(Hi);
end;
until Lo > Hi;
if Hi > iLo then QuickSort(A, iLo, Hi);
if Lo < iHi then QuickSort(A, Lo, iHi);
if Terminated then Exit;
end;
Он работает, но разделение кажется странным. Или это общая оптимизация?
Я сделал тест со случайными значениями, и вы получите случаи, когда Mid не находится в Hi, Lo или между ними. И в этом случае «шарнир» попадает между двумя значениями. Это связано с тем, что он увеличивает и Lo, и Hi после флип, даже когда одно из них имеет значение Mid. Не подсказка, которую вы держите за значение Pivot, и делайте еще один QuickSort с левой и с правой стороны. Это оптимизация для равных ключевых значений?
Кроме того, эта реализация имеет равную ценность? Будет ли 3-стороннее разделение лучше?
Я думаю, что проблема заключается в описании YouTube этой проблемы: http://www.youtube.com/watch?v = Z5nSXTnD1I4 Он содержит фактическое размещение элемента и только быструю сортировку по обе стороны от него, но вместо этого он может находиться между двумя элементами, если только в левой части меньше или меньше, а справа - меньше или одинаково. И нет необходимости делать последнюю очистку, когда вы знаете, что эта часть держится? –
Это болотный стандарт Quicksort. Я не понимаю, в чем ваш вопрос. –
3-стороннее разделение должно решить это, хотя? Поскольку вы будете перемещать ключевые элементы из центра во время работы, затем переверните их и сделайте quicksort вне этой области. Но я все еще чувствую, что он должен был переместить ключевой элемент в положение Lo и уменьшить его? Иначе это будет делать много дополнительной работы? –