
Лекция 12
Сортировка массивов
Для определённости будем считать, что элементы одномерного массива A – вещественные числа (A1, A2, A3, … An), а расставить их требуется в порядке возрастания.
Сортировка вставками
Алгоритм, в нескольких словах, таков.
На «первом» шаге вообще ничего не делается.
На втором шаге берётся второй элемент (A2) и сравнивается с первым (A1). Если второй элемент меньше первого, они обмениваются местами. Результат – два элемента упорядочены.
На i-ом шаге (теперь i = 3, 4, 5, … , n) берётся i-ый элемент (Ai) и сравнивается с теми элементами Aj , что расположены слева от него: j = i - 1, j = i - 2, j = i - 3, и т.д. – так до тех пор, пока выполняется неравенство Ai < Aj. В последний раз, когда это неравенство будет выполнено, переменная j примет значение, равное новому месту для Ai – такому, куда нужно Ai вставить.
Например, пусть i = 5, а первые 5 элементов массива таковы: 4, 3, 9, 11, 5. В последний раз Ai < Aj при j = 3. Следовательно, число 5 должно встать на третью позицию, подвинув числа 9, 11 вправо на 1 шаг. Результат – i элементов упорядочены.
Текст процедуры:
procedure InsertSort;
var
i, j: int64;
x: single;
begin
nMove:=0;
nCompare:=0;
for i := 2 to nCurr do
begin
x := A[i];
Inc(nMove);
j := i;
while (j > 1) and (x < A[j - 1]) do
begin
// Попаданий в тело цикла будет на 1 меньше,
// чем вычислений логического условия «(j > 1) and (x < A[j - 1])».
Inc(nCompare);
A[j] := A[j - 1];
Inc(nMove, 2);
Dec(j);
end;
if j > 1 then
begin
// Сюда попали => при последнем j проверка «(x < A[j - 1])» была
Inc(nMove);
// Прверка условия «(x < A[j - 1])» требует одного перемещения
Inc(nCompare);
end;
if j <> i then
begin
A[j] := x;
Inc(nMove);
end;
end;
end;
Назначение переменных:
nCurr – текущее количество элементов в массиве,
nMove – найденное количество перемещений.
nCompare – найденное количество сравнений.
Количество сравнений (nCompare):
i |
Min |
Max |
Average |
2 |
1 |
1 |
1 |
3 |
1 |
2 |
3/2 |
4 |
1 |
3 |
2 |
… |
… |
… |
… |
|
1 |
i-1 |
i/2 |
… |
… |
… |
… |
n |
1 |
n-1 |
1 |
∑ |
n-1 |
n2/2-n/2 |
n2/4+n/4-1/2 |
Количество переносов (nMove):
i |
Min |
Max |
Average |
2 |
2 |
4 |
3 |
3 |
2 |
6 |
4 |
4 |
2 |
8 |
5 |
… |
… |
… |
… |
i |
2 |
2i |
i+1 |
… |
… |
… |
… |
n |
2 |
2n |
n+1 |
∑ |
2(n-1) |
n2+n-2 |
n2/2-3n/2-2 |