Авторизация

Логин: Пароль:
Регистрация Забыли свой пароль?

Сортировка

Страницы: 1
Сортировка
Ребят, а давайте здесь соберем алгоритмы сортировки, а то напрягает иногда по всему Интернету лазить. Начну сам.
Итак первый алгоритм, наверное, самый простой - сортировка вставкой. Суть алгоритма в том, что сначала формируется массив элементов в конце которого выделяется дополнительная ячейка, затем сравниваем элемент стоящий перед пустой ячейкой, если он, конечно, не первый. Если элемент больше то передвигаем стоящий в ячейки элемент и у нас получается смещение пустой ячейки. Когда мы дойдем до элемента который будет меньше, то в пустую ячейку вставляем анализируемый элемент. Все это можно реализовать так

Код
Var X,Y : array[1..10000] of integer;
K,i,j : integer;
Begin
{Определяем размер массива A (K) и заполянем его}
…
{дальше сам алгоритм сортировки}
for i:=1 to K do
begin
j:=i;
while (j>1) and (B[j-1]>A[i]) do
begin
B[j]:=B[j-1];
j:=j-1;
end;
B[j]:=A[i];
end;
{Выводим отсортированный массив B}
…
End.
Изменено: Артём Кулинич - 26.11.2009 20:01:55
А давайте. Я тоже добавлю. Есть хороший алгоритм, который применяется когда нужно сортировать большой массив. В этих случаях число перестановок может существенно замедлить процесс сортировки. Поэтому делают так. За один проход выбирают самый максимальный и самый минимальный элемент. Затем минимальный помещают в начало , а максимальный в конец. В результате за количество проходов в двое меньшее числу элементов мы получаем полностью отсортированный массив. Называется алгоритм- сортировка Шейкером

Код
Program ShakerSort;
Var A : array[1..1000] of integer;
N,i,j,p : integer;
Min, Max : integer;
Begin
{Определение размера массива A — N) и его заполнение}
…
{сортировка данных}
for i:=1 to n div 2 do
begin
if A[i]>A[i+1] then
begin
Min:=i+1;
Max:=i;
end
else
begin
Min:=i;
Max:=i+1;
end;
for j:=i+2 to n-i+1 do
if A[j]>A[Max] then
Max:=j
else
if A[j]<A[Min] then
Min:=j;
{Обмен элементов}
P:=A[i];
A[i]:=A[min];
A[min]:=P;
if max=i then
max:=min;
P:=A[N-i+1];
A[N-i+1]:=A[max];
A[max]:=P;
end;
{Вывод отсортированного массива A}
…
End. 
Добавлю еще один алгоритм.
Алгоритм называется - пузырьковая сортировка. Смысл в том, что берутся два соседних элемента массива и меняются местами если элемент с меньшим индексом, больше элемента с большим индексом.
Реализация очень простая
Код
Var A : array[1..10000] of integer;
K,i,j,p : integer;
Begin
{Определение размера массива A (K) и его заполнение}
…
{сортировка данных}
for i:=1 to K do
for j:=1 to K-i do
if A[j]>A[j+1] then
begin {Обмен элементов}
p:=A[j];
A[j]:=A[j+1];
A[j+1]:=P;
end;
{Вывод отсортированного массива A}
…
End. 
И еще один.
Называется - сортировка слиянием.
Смысл заключается в том, что массив разделяется на две части. Каждая сортируется и потом оба массива сливаются вместе.

Код
Var A,B : array[1..1000] of integer;
N : integer;
Procedure Sliv(p,q : integer); {процедура сливающая массивы}
Var r,i,j,k : integer;
Begin
r:=(p+q) div 2;
i:=p;
j:=r+1;
for k:=p to q do
if (i<=r) and ((j>q) or (a[i]<a[j])) then
begin
b[k]:=a[i];
i:=i+1;
end
else
begin
b[k]:=a[j];
j:=j+1;
end ;
for k:=p to q do
a[k]:=b[k];
End;
Procedure Sort(p,q : integer); {p,q — индексы начала и конца сортируемой части массива}
Begin
if p<q then {массив из одного элемента тривиально упорядочен}
begin
Sort(p,(p+q) div 2);
Sort((p+q) div 2 + 1,q);
Sliv(p,q);
end;
End;
Begin
{Определение размера массива A — N) и его заполнение}
…
{запуск сортирующей процедуры}
Sort(1,N);
{Вывод отсортированного массива A}
…
End. 
Я тоже еще один вспомнил
Суть примерна таже, что и в алгоритме слияние, но разделение массива происходит при условии, что любой элемент первой части, меньше минимального элемента второй части. Обычно такое разделение происходит относительно заданного числа. Если элемент больше числа он попадает во второй массив, если меньше в первой. А затем оба массива сортируются
Алгоритм, кстати, работает очень быстро, поэтому так и называется - быстрая сортировка
Реализуется так
Код
Program QuickSort;
Var A : array[1..1000] of integer;
N,T : integer;
Procedure Sort(p,q : integer); {p,q — индексы начала и конца сортируемой части массива}
Var i,j,r : integer;
Begin
if p<q then {массив из одного элемента тривиально упорядочен}
begin
r:=A[p];
i:=p-1;
j:=q+1;
while i<j do
begin
repeat
i:=i+1;
until A[i]>=r;
repeat
j:=j-1;
until A[j]<=r;
if i<j then
begin
T:=A[i];
A[i]:=A[j];
A[j]:=T;
end;
end;
Sort(p,j);
Sort(j+1,q);
end;
End;
Begin
{Определение размера массива A — N) и его заполнение}
…
{запуск сортирующей процедуры}
Sort(1,N);
{Вывод отсортированного массива A}
…
End. 
Ну и я добавлю какой знаю. Алгортим достаточно простой и не содержит вложенных циклов. Называется - сортировка подсчетом. Как объяснить не знаю, но думаю по реализации Вы все поймете.

Код
Var A,B : array[1..1000] of byte;
C : array[byte] of integer;
N,i : integer;
Begin
{Определение размера массива A (N) и его заполнение}
…
{сортировка данных}
for i:=0 to 255 do
C[i]:=0;
for i:=1 to N do
C[A[i]]:=C[A[i]]+1;
for i:=1 to 255 do
C[i]:=C[i-1]+C[i];
for i:=N downto 1 do
begin
B[C[A[i]]]:=A[i];
C[A[i]]:=C[A[i]]-1; {здесь мы избегаем возможности записи двух одинаковых чисел в одну ячейку}
end;
{Вывод массива B}
…
End. 
Да алгоритм и правда легко реализуется. Объясню как функционирует. Сначала заполняем массив C нулями, и для каждого A[i] увеличить C[A[i]] на 1. Далее подсчитывается число элементов равных или меньших текущего. Для этого каждый C[j], начиная с C[1], увеличивают на C[j - 1]. На последнем шаге алгоритма читается входной массив с конца и в каждый B[C[A[i]]] записывается A[i], при этом значение C[A[i]] уменьшается на 1. Надеюсь понятно объяснил.
Нормально объяснил. Это реализация кстати устойчивая из-за использования дополнительного массива B, чего нельзя сказать о простейщем варианте реализации алгоритма. Но его я приводить не буду. Ни к чему.
Добавляю, алгоритм цифровой сортировки. Применяется для сортировки целых неотрицательных чисел большого диапозона. Основная идея в том, что сначало сортируем числа по младшему разряду, потом устойчивой сортировкой по втором, третьему и т.д. В качестве устойчивой можно использовать сортировку подсчетом.
Реализация алгоритма

Код
Var A,B : array[1..1000] of word;
N,i : integer;
t : longint;
Procedure Sort; {сортировка подсчетом}
Var C : array[0..9] of integer;
j : integer;
Begin
For j:=0 to 9 do
C[j]:=0;
For j:=1 to N do
C[(A[j] mod (t*10)) div t]:= C[(A[j] mod (t*10)) div t]+1;
For j:=1 to 9 do
C[j]:=C[j-1]+C[j];
For j:=N downto 1 do
begin
B[C[(A[j] mod (t*10)) div t]]:=A[j];
C[(A[j] mod (t*10)) div t] := C[(A[j] mod (t*10)) div t]-1;
end;
End;
Begin
{Определение размера массива A (N) и его заполнение}
…
{сортировка данных}
t:=1;
for i:=1 to 5 do
begin
Sort;
A:=B;
t:= t*10;
end;
{Вывод массива A}
…
End. 
Кому интересны другие виды сортировки, посмотрите в Википедии - там упомянуты многие виды сортировки. Правда, примеры кода не для всех есть, насколько я помню. Зато можно хотя бы по названию найти в сети исходники.
Accende lumen sensibus, infude ainorem corbidus!
Пузырьковая сортировка самая простая, а если поставить флаг на перестановки, то и довольно эффективная.
пока ты не доволен жизнью - она проходит...
Наиболее эффективной показала себя так называемая сортировка кучей или пирамидальная сортировка. Для ее реализации правда нужно иметь некоторый запас знаний в теории графов. Идея алгоритма заключается в проталкивании самого большого элемента дерева в его корень и последующее удаление корня.
Код
const
   MaxN = 1500000;
var
   a: array[1..MaxN] of LongInt;
   n, hs, i: LongInt;

procedure swap(var x, y: LongInt);
var z: LongInt;
begin
   z := x; x := y; y := z;
end;

procedure pushdown(j: LongInt);
var max: LongInt;
begin
    {выбор максимального из трех элемента}
    if (2*j <= hs) and (a[j] < a[2*j])
               then  max := 2*j
               else  max := j;
    if (2*j+1 <= hs) and (a[max] < a[2*j+1])
               then  max := 2*j+1;
    {если свойство (1) не выполняется,
     рекурсивно запускаем процедуру снова}
    if max <> j then begin
                       swap(a[max], a[j]);
                       pushdown(max)
                    end
end;

procedure heapsort;
begin
    hs := n;
    {строим кучу}
    for i := n div 2 downto 1 do
        pushdown(i);
    {постепенно выкидываем из кучи максимальный элемент}
    for i := n downto 2 do
       begin
           swap(a[1], a[i]); {максимальный элемент - в конец кучи}
           dec(hs);    {уменьшаем кучу, одновременно выкидывая
                        из нее максимальный элемент}
           pushdown(1) {для корня после обмена свойство (1) нарушено}
       end
end;

procedure Init;
begin
    {заполняем массив чем нибуть}
end;

procedure Save;
begin
    {Оперируем полученными данными}
end;

begin
    Init;
    heapsort;
    Save;
end.


В бытность участия в олимпиадах правда ей почти не пользовался - слишком много времени на реализацию всего лишь сортировки уходит. Идеальна для меня лично "быстрая сортировка" - хорошая скорость работы, не так уж много побочных переменных и загаживания памяти и вполне простая реализация.
Accende lumen sensibus, infude ainorem corbidus!
Цитата
Идеальна для меня лично "быстрая сортировка" - хорошая скорость работы, не так уж много побочных переменных и загаживания памяти и вполне простая реализация.

Согласен, сам обычно ей пользуюсь.
Страницы: 1
Читают тему (гостей: 1, пользователей: 0, из них скрытых: 0)