- Lektsia - бесплатные рефераты, доклады, курсовые работы, контрольные и дипломы для студентов - https://lektsia.info -

Разработка алгоритма сортировки прямым выбором



Алгоритм сортировки прямым выбором в некотором смысле противоположен сортировке прямыми включениями.

При прямом включении на каждом шаге рассматривается только один очередной элемент входной последовательности и все элементы готовой последовательности для нахождения места включения.

При прямом выборе для поиска одного элемента с наименьшим ключом просматриваются все элементы входной последовательности и найденный элемент помещается как очередной элемент в конец готовой последовательности.

Метод сортировки прямым выбором основан на следующих правилах:

· Выбирается элемент с наименьшим ключом.

· Он меняется местами с первым элементом a0.

· Затем эти операции повторяются с оставшимися n-1 элементами, n-2 элементами и так далее до тех пор, пока не останется один, самый большой элемент.

Таблица 1

0,57 -0,11 0,27 0,48 0,05 -24 0,09 1,46 -0,39 -1,00
-24 -0,11 0,27 0,48 0,05 0,57 0,09 1,46 -0,39 -1,00
-24 -1,00 0,27 0,48 0,05 0,57 0,09 1,46 -0,39 -0,11
-24 -1,00 -0,39 0,48 0,05 0,57 0,09 1,46 0,27 -0,11
-24 -1,00 -0,39 -0,11 0,05 0,57 0,09 1,46 0,27 0,48
-24 -1,00 -0,39 -0,11 0,05 0,57 0,09 1,46 0,27 0,48
-24 -1,00 -0,39 -0,11 0,05 0,09 0,57 1,46 0,27 0,48
-24 -1,00 -0,39 -0,11 0,05 0,09 0,27 1,46 0,57 0,48
-24 -1,00 -0,39 -0,11 0,05 0,09 0,27 0,48 0,57 1,46
-24 -1,00 -0,39 -0,11 0,05 0,09 0,27 0,48 0,57 1,46
-24 -1,00 -0,39 -0,11 0,05 0,09 0,27 0,48 0,57 1,46
-24 -1,00 -0,39 -0,11 0,05 0,09 0,27 0,48 0,57 1,46
-24 -1,00 -0,39 -0,11 0,05 0,09 0,27 0,48 0,57 1,46

 

 

Алгоритм сортировки прямым выбором

Блок-схема 1. Процедура сортировки массива методом прямого выбора.

 

Прямой выбор
 
Прямой выбор
j,A,i
A[i],A[j]
Findmin
Swap
Input N, A[1..N]
j:=0 to N-1
Swap
Swap
Input i,j
t:=i  
i:=j  
j:=t  
A[u]<min
Findmin
 
Findmin
Input j,A,i
u:=j+1 to N-1
i:=j,min:=A[j]
min:=A[u]
i:=u
нет
да

 

 

Текст процедуры для сортировки прямым выбором

procedureFindMin(startindex:integer;M:ar;varlowindex: integer);{Перебирает массив начиная с заданного индекса и находим минимальный элемент}

varmin,u:integer;

Begin

lowindex:= startindex;

min := M[startindex];

foru:=startindex+1 toN-1 do

Begin

inc(Psrav);

ifM[u]< min then

Begin

min := M[u];

lowindex:= u;

end;

end;

end;

procedureswap(varx,y,z: integer);{Меняем местами заданные элементы массива}

vart: integer;

Begin

t := x;

x := y;

y := t;

inc(z);

end;

procedurePryamoi_vibor(M:Ar);{Сортирует массив с помощью прямого выбора}

Var

j:integer;

Begin

forj:=0 toN-1 do

Begin

FindMin(j,m,i);

swap(M[j],M[i],Pper);

End

end;

 

Шейкерная сортировка

Разработка алгоритма шейкерной сортировки

Шейкерная сортировка − разновидность пузырьковой сортировки. Отличается тем, что просмотры элементов выполняются один за другим в противоположных направлениях, при этом большие элементы стремятся к концу массива, а маленькие - к началу. Своим появлением эта сортировка обязан такому недостатку сортировки «пузырьком», при котором «лёгкие пузырьки» всплывают за один проход, а «тяжёлые» − тонут за несколько. Такая ассиметрия и вызвала появление новой сортировки, на каждом шаге которой осуществляется проход как в одну сторону, так и в другую. Таким образом, на каждом шаге «лёгкий пузырёк» всплывает на поверхность, а «тяжёлый» − тонет.

Метод этот получил название шейкерной сортировки.

Таблица 2

Шаг Направление движения Элементы массива
Справа-налево
Слева-направо 10 ||
Справа-налево 10 || || 75
Слева-направо 17 || || 75
Справа-налево 17 || || 70
Слева-направо 18 || || 70

Серым цветом в таблице выделена та часть массива, которая исключается из просмотра.

 

 

Алгоритм шейкерной сортировки

Блок-схема 2. Процедура шейкерной сортировки массива.

l:=2; r:=N-1; k:=R  
Input A[N]
Шейкер
A1
Шейкер
A2 j:=r downto l-1
a[j-1] > a[j]
нет
да
A2
A3 j:=l to r
A[j-1] > A[j]
нет
да
A3
r:=k-1
A1 l>r
L:=k+1
A[j],A[j-1]  
Swap
k:=j
A[j],A[j-1]  
k:=j
Swap

Текст процедуры шейкерной сортировки

procedureShaker(M:Ar);{Сортирует массив методом смешивания}

Var

j,k,l,r:integer;

Begin

L:=2;

R:=N-1;

k:=R;

Repeat

Begin

forj:=r downtol-1 do

Begin

ifM[j-1] > M[j] then

Begin

swap(M[j],M[j-1],Sper);

k:=j;

end;

inc(Ssrav);

end;

L:=k+1;

forj:=l tor do

Begin

ifM[j-1]> M[j] then

Begin

swap(M[j],M[j-1],Sper);

k:=j;

end;

inc(Ssrav);

end;

r:=k-1;

end;

untilL>R;

end;

Быстрая сортировка

Разработка алгоритма быстрой сортировки

Быстрая сортировка, часто называемая qsort по имени реализации в стандартной библиотеке языка Си — широко известный алгоритм сортировки, разработанный английским информатиком Чарльзом Хоаром. Один из быстрых известных универсальных алгоритмов сортировки массивов (в среднем O(n log n) обменов при упорядочении n элементов). Этот улучшенный метод сортировки основан на обмене.

Если количество элементов в массиве не многим меньше максимального их значения, то в данном случае наиболее эффективным и по быстродействию, и по простоте является быстрая сортировка. Основные достоинства этого алгоритма состоят в том, что он точечный (использует лишь небольшой дополнительный стек), в среднем требует только около N log N операций для того, чтобы отсортировать N элементов, и имеет экстремально короткий внутренний цикл. Недостатки алгоритма состоят в том, что он рекурсивен (реализация очень затруднена когда рекурсия недоступна), в худшем случае он требует N2 операций, кроме того он очень "хрупок": небольшая ошибка в реализации, которая легко может пройти незамеченной, может привести к тому, что алгоритм будет работать очень плохо на некоторых файлах.

Основная идея алгоритма быстрой сортировки состоит в том, что случайным образом выбирается некоторый элемент массива x, после чего массив просматривается слева, пока не встретится элемент a[i] такой, что a[i] > x, а затем массив просматривается справа, пока не встретится элемент a[j] такой, что a[j] < x. Эти два элемента меняются местами, и процесс просмотра, сравнения и обмена продолжается, пока мы не дойдем до элемента x. В результате массив окажется разбитым на две части - левую, в которой значения ключей будут меньше x, и правую со значениями ключей, большими x.

Далее процесс рекурсивно продолжается для левой и правой частей массива до тех пор, пока каждая часть не будет содержать в точности один элемент. Понятно, что как обычно, рекурсию можно заменить итерациями, если запоминать соответствующие индексы массива. Проследить этот процесс можно на примере таблицы (таблица 2).

Таблица 3

Начальное состояние массива 8 23 5 65 44 33 1 6
Шаг 1. (в качестве x выбирается a[4]) 8 23 5 65 44 33 1 6 |-------------| 8 23 5 6 44 33 1 65
Шаг 2. (в подмассиве a[1..7] за x выбирается a[4]) 8 23 5 6 44 33 1 65 |-------------------| 1 23 5 6 44 33 8 65 |-----| 1 6 5 23 44 33 8 65
Шаг 3. (в подмассиве a[1..3] в качестве x выбирается a[2]) 1 6 5 23 44 33 8 65 |--| 1 5 6 23 44 33 8 65
Шаг 4. (в подмассиве a[4..7] в качестве x выбирается a[5]) 1 5 6 23 44 33 8 65 |-----| 1 5 6 23 8 33 44 65
Шаг 5. (в подмассиве a[4..6] в качестве x выбирается a[5]) 1 5 6 23 8 33 44 65 |---| 1 5 6 8 23 33 44 65

 

 

Алгоритм быстрой сортировки массива.

Блок-схема 3. Процедура быстрой сортировки массива

 

 

QSort
i:=L,j:=R
A1
A1i>j
Qsort
A[N],L,R
i <= j
w:=A[(L+R)div 2]
A2 A[i]<w
A2
inc(i)
A3 w <A[j]
A3
dec(j)
A[i],A[j]
inc(i),dec(j)
Swap
L < j
i <R
L,j
I,R
QSort  
QSort  
да
нет
нет
нет
да
да

Текст процедуры быстрой сортировки

procedureQsort(l,r:integer);{Сортирует массив Быстрой сортировкой}

vari,j,w:integer;

Begin

i := l; j := r;

w := Q[(l+r) div2];

Repeat

while(Q[i] < w) do begininc(i); inc(Qsrav); end;

while(w < Q[j]) do begindec(j); inc(Qsrav); end;

if(i <= j) then

Begin

swap(Q[i],Q[j],Qper);

inc(i); dec(j);

end;

until(i > j);

if(l < j) thenqSort(l,j);

if(i < r) thenqSort(i,r);

end;


Графическая работа

Для того, чтобы изобразить гистограммы и таблицы по полученным данным, воспользуемся процедурами из модулей GraphABC и ABCobjects.

Готовый алгоритм построения гистограмм для значений из массива Q выглядит следующим образом:

 

ProcedureGist;{Строит гистрограмму одного массива}

Var

a,c,b:integer;

x:real;

Begin

SetBrushColor(clgreen);

Textout(500,5,'Быстрая');

SetBrushColor(clDarkOrchid);

Textout(600,5,'Прямая');

SetBrushColor(clHotPink);

Textout(700,5,'Шейкерная');

 

SetBrushColor(clmoneygreen);

Textout(95,a+55,'Перемещений');

Textout(355,a+55,'Сравнений');

Textout(605,a+55,'Время в мсек.');

 

x:=Qper;

Ifx<Pper thenx:=Pper;

Ifx<Sper thenx:=Sper;

a:=round(90/(x/Qper));

b:=round(90/(x/Pper));

c:=round(90/(x/Sper));

 

SetBrushColor(clgreen);

FillRectangle(10,y+165,70,y+165-a+2);

SetBrushColor(clDarkOrchid);

FillRectangle(100,y+165,160,y+165-b+2);

SetBrushColor(clHotPink);

FillRectangle(190,y+165,250,y+165-c+2);

 

x:=Qsrav;

Ifx<Psrav thenx:=Psrav;

Ifx<Ssrav thenx:=Ssrav;

a:=round(90/(x/Qsrav));

b:=round(90/(x/Psrav));

c:=round(90/(x/Ssrav));

 

SetBrushColor(clgreen);

FillRectangle(280,y+165,340,y+165-a+2);

SetBrushColor(clDarkOrchid);

FillRectangle(370,y+165,430,y+165-b+2);

SetBrushColor(clHotPink);

FillRectangle(460,y+165,520,y+165-c+2);

 

x:=Qtime;

Ifx<Ptime thenx:=Ptime;

Ifx<Stime thenx:=Stime;

a:=round(90/(x/Qtime));

b:=round(90/(x/Ptime));

c:=round(90/(x/Stime));

 

SetBrushColor(clgreen);

FillRectangle(550,y+165,610,y+165-a+2);

SetBrushColor(clDarkOrchid);

FillRectangle(640,y+165,700,y+165-b+2);

SetBrushColor(clHotPink);

FillRectangle(730,y+165,790,y+165-c+2);

 

setpencolor(clblack);

SetBrushColor(clmoneygreen);

 

Textout(10,y+185,inttostr(Qper));

Textout(100,y+185,inttostr(Pper));

Textout(190,y+185,inttostr(Sper));

 

Textout(280,y+185,inttostr(Qsrav));

Textout(370,y+185,inttostr(Psrav));

Textout(460,y+185,inttostr(Ssrav));

 

str(Qtime:8:4,Qtimest);

str(Ptime:8:4,Ptimest);

str(Stime:8:4,Stimest);

Textout(550,y+185,Qtimest);

Textout(640,y+185,Ptimest);

Textout(730,y+185,Stimest);

end;