Быстрая сортировка участка массива R от p до rr происходит следующим образом:
procedure QuickSortR(p,rr:longint); var q: longint; begin if p < rr then begin q:=Partition(p,rr); QuickSortR(p,q); QuickSortR(q+1, rr); end; end;
Рассмотрим теперь подробнее реализацию функции Partition(p, rr).
function Partition(p, rr:longint):longint; var i, j, z : longint; x, t : single; begin x:= R[p]; i:= p - 1; j:= rr + 1; while i < j do begin repeat j:= j - 1 until R[j] ≤ x; repeat i:= i + 1 until R[i] ≥ x; if i < j then begin t:= R[i]; R[i]:= R[j]; R[j]:= t; z:= B[i]; B[i]:= B[j]; B[j]:= z; z:= E[i]; E[i]:= E[j]; E[j]:= z; end; end; Partition:= j; end;
В качестве "граничного элемента" принимается X = R[p]. Далее заводим два указателя: i — при просмотре элементов с начала сортируемого участка, и j — при просмотре элементов с конца сортируемого участка. Пока i < j, выполняется слeдующее: находим R[j] — первый с конца элемент меньше Х, и R[i] — первый с начала элемент, больший X. Если i < j, то меняем местами элементы R[i] и R[j]:
t:= R[i], R[i]:= R[j]; R[j]: = t;
Поскольку в данной задаче нужно синхронно с перемещением весов ребер R[k] перемещать также вершины их начала и конца, выполняются также соответствующие операции:
z:= B[i]; B[i]:= B[j]; B[j]:= z; z:= E[i]; E[i]:= E[j]; E[j]:= z;
По завершении цикла "пока i < j" мы и получаем границу "разделения" Partition:= j. Понятно, что вызывать алгоритм быстрой сортировки нужно, передавая ему вначале номера начального и конечного элементов массива, например, для задачи "Веревочный телеграф": QuickSortR(1, N * (N - X) div 2).
На следующем шаге рассмотрим решение олимпиадной задачи.