Сортування Шелла
![]() Сортува́ння Ше́лла — це алгоритм сортування, що є узагальненням сортування включенням. Алгоритм базується на двох тезах:
Тому сортування Шелла виконує декілька впорядкувань включенням, кожен раз порівнюючи і переставляючи елементи, що розташовані на різній відстані один від одного. Сортування Шелла не є стабільним. ІсторіяСортування Шелла названо на честь автора — Дональда Шелла, який опублікував цей алгоритм у 1959[1] році. В деяких пізніших друкованих виданнях алгоритм називають сортуванням Шелла-Мацнера, за ім'ям Нортона Мацнера. Але сам Мацнер стверджував: «Мені не довелось нічого робити з цим алгоритмом, і моє ім'я не має пов'язуватись з ним».[2] Ідея алгоритмуНа початку обираються m-елементів: , причому, . Потім виконується m впорядкувань методом включення, спочатку для елементів, що стоять через , потім для елементів через і т. д. до . Ефективність досягається тим, що кожне наступне впорядкування вимагає меншої кількості перестановок, оскільки деякі елементи вже стали на свої місця. ПсевдокодСам алгоритм не залежить від вибору m і d, тому будемо вважати, що вони задані. 1. for to 2. do for to 3. do 4. 5. while and 6. do 7. 8. Коректність алгоритмуОскільки то на останньому кроці виконується звичайне впорядкування включенням всього масиву, а отже кінцевий масив буде впорядкованим. Час роботиЧас роботи залежить від вибору значень елементів масиву d. Існує декілька підходів вибору цих значень:
то час роботи алгоритму становить (Sedgewick, 1986[3]).
Приклад роботиПроілюструймо роботу алгоритму на вхідному масиві A = (5,16,1,32,44,3,16,7), d = (5,3,1).
Отже, весь масив впорядковано за 9 операцій обміну. Реалізація (Паскаль/DELPHI)PROGRAM MyVerShellSort;
{$APPTYPE CONSOLE}
USES SysUtils;
TYPE massive=array[1..100] of integer;
VAR A:massive; n:integer;
procedure RndArrInput(var a1:massive; n1:integer);
var i1:integer;
begin
randomize;
for i1:=1 to n1 do
a1[i1]:=10-random(20);
end;
procedure Arroutput(a2:massive; n2:integer);
var i2:integer;
begin
for i2:=1 to n2 do
write(a2[i2],' ');
end;
procedure change (var k,l:integer);
var tmp:integer;
begin
tmp:=k; k:=l; l:=tmp;
end;
procedure ShellSort(var A:massive; N:integer);
var i,j,h:integer;
begin
h:=N div 2;
while h>0 do
begin
for i:=1 to N-h do
begin
j:=i;
while (j>=1)and(A[j]>A[j+h]) do
begin
change(a[j],a[j+h]);
dec(j);
end;
end;
h:=h div 2;
end;
end;
BEGIN
writeln('enter data:');
readln(n);
RndArrInput(a,n);
ArrOutPut(a,n); readln;
ShellSort(a,n);
ArrOutPut(a,n);
readln;
END.
Реалізація на C++void sort_shell(int *a, int N)
{
for (int d = N/2; d >= 1; d /= 2)
for (int i = d; i < N; i++)
for (int j = i; j >= d && a[j-d] > a[j]; j -= d)
swap(a[j], a[j-d]);
}
Примітки
Посилання
|
Portal di Ensiklopedia Dunia