Добавил:
Upload
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Чет про программирование / туф / 13_sort / main
.pas {$mode objfpc}
var
a: array of integer;
n, i: integer;
procedure swap(var i, j: integer);
var t: integer;
begin
t := i; i := j; j := t;
end;
procedure qsort(l, r: integer);
var
i, j: integer;
x: integer;
begin
write(l, ' ', r, ': ');
for i := l to r do
write(a[i], ' ');
writeln;
x := a[l + random(r-l+1)]; // берём сам элемент, а не его индекс
i := l;
j := r;
while i < j do begin // Theta(r-l+1)
while a[i] < x do inc(i); // выхода за пределы массива не произойдёт
while a[j] > x do dec(j);
if i <= j then begin
swap(a[i], a[j]);
inc(i);
dec(j);
end;
end;
if l < j then qsort(l, j);
if i < r then qsort(i, r);
end;
begin
randomize;
read(n);
setlength(a, n);
for i := 0 to n-1 do
read(a[i]);
qsort(0, n-1);
for i := 0 to n-1 do
write(a[i], ' ');
writeln;
end.
{
Кормэн
Ахо, Хопкрофт, Ульман "Структуры данных и алгоритмы"
Быстрая сортировка (quick sort)
1. x - опорный элемент
2. <= x | >= x
3. рекурсивно отсортировать две половинки
Как выполнить шаг 2?
Анализ времени работы
Худший случай: в качестве опорного выбирается наибольший элемент (наименьший элемент)
T(n) = T(n-1) + Theta(n)
т.е. по поределению Theta
существует c > 0, n0:
если рассматривать n > n0:
T(n) <= T(n-1) + cn;
T(n) <= cn + c(n-1) + c(n-2) + ... + c(n0+1) + c1 <= cn(n-1)/2
T(n) = O(n^2);
В лучшем случае:
опорный элемент выбирается средним по значению (б/д)
T(n) <= T(ceil(n/2)) + T(floor(n/2)) + cn
=> T(n) = O(nlogn)
1. как в сортировке слиянием
2. методом математической индукции
Классификация алгоритмов сортировки:
- по асимптотической сложности O(n^2) (пузырёк, сортировка вставками, сортировка обемном),
O(nlogn) (сортиовка слиянием)
O(nlogn) в среднем (быстрая сортировка)
O(n+m) (карманная сортировка)
- по характеру сортируемых элементов
- сортировки, основанные на сравнениях
- сортировки элементов из ограниченного диапазона (карманная сортировка)
- сортировки, основанные на разрядах (radix sort)
}
var
a: array of integer;
n, i: integer;
procedure swap(var i, j: integer);
var t: integer;
begin
t := i; i := j; j := t;
end;
procedure qsort(l, r: integer);
var
i, j: integer;
x: integer;
begin
write(l, ' ', r, ': ');
for i := l to r do
write(a[i], ' ');
writeln;
x := a[l + random(r-l+1)]; // берём сам элемент, а не его индекс
i := l;
j := r;
while i < j do begin // Theta(r-l+1)
while a[i] < x do inc(i); // выхода за пределы массива не произойдёт
while a[j] > x do dec(j);
if i <= j then begin
swap(a[i], a[j]);
inc(i);
dec(j);
end;
end;
if l < j then qsort(l, j);
if i < r then qsort(i, r);
end;
begin
randomize;
read(n);
setlength(a, n);
for i := 0 to n-1 do
read(a[i]);
qsort(0, n-1);
for i := 0 to n-1 do
write(a[i], ' ');
writeln;
end.
{
Кормэн
Ахо, Хопкрофт, Ульман "Структуры данных и алгоритмы"
Быстрая сортировка (quick sort)
1. x - опорный элемент
2. <= x | >= x
3. рекурсивно отсортировать две половинки
Как выполнить шаг 2?
Анализ времени работы
Худший случай: в качестве опорного выбирается наибольший элемент (наименьший элемент)
T(n) = T(n-1) + Theta(n)
т.е. по поределению Theta
существует c > 0, n0:
если рассматривать n > n0:
T(n) <= T(n-1) + cn;
T(n) <= cn + c(n-1) + c(n-2) + ... + c(n0+1) + c1 <= cn(n-1)/2
T(n) = O(n^2);
В лучшем случае:
опорный элемент выбирается средним по значению (б/д)
T(n) <= T(ceil(n/2)) + T(floor(n/2)) + cn
=> T(n) = O(nlogn)
1. как в сортировке слиянием
2. методом математической индукции
Классификация алгоритмов сортировки:
- по асимптотической сложности O(n^2) (пузырёк, сортировка вставками, сортировка обемном),
O(nlogn) (сортиовка слиянием)
O(nlogn) в среднем (быстрая сортировка)
O(n+m) (карманная сортировка)
- по характеру сортируемых элементов
- сортировки, основанные на сравнениях
- сортировки элементов из ограниченного диапазона (карманная сортировка)
- сортировки, основанные на разрядах (radix sort)
}