[Оглавление] | [<< страница] | [>>страница] |
Метод Шелла является улучшением метода сортировки с помощью прямого включения и основан на сортировке посредством включений с уменьшающимися расстояниями. Сначала отдельно группируются и сортируются методом прямых включений элементы, отстоящие друг от друга на некотором расстоянии h1, затем на расстоянии h2 < h1 и т.д., последнее расстояние должно быть равно 1. Таким образом, если для сортировки будет использовано t расстояний, то ht=1, hi+1
Учитывая этот факт имеет смысл использовать такие последовательности (записаны в обратном порядке): 1, 4, 13, 40, 121, ...,т.е. hk-1 = 3hk+ 1,ht=1, t = [Iog3n]- 1 или 1,3,7, 15,31, ..., т.е. hk-1 = 2hk + 1,ht= 1, t = [Iog2n] - 1. В последнем случае для сортировки n элементов методом Шелла затраты пропорциональны n1,2, что значительно лучше n2 , но хуже n*log2n. Часто используют h1 = n/2, h2 = n/4, ..., и т.д.
На каждом шаге методом включения сортируются группы a1, а1+h, a1+2h,…,a1+kh, 1+kh≤n; a2,a2+h,… . Так как начальный шаг является наибольшим, то число элементов массива в начальной группе является наименьшим, например, если h = n/2, то группируются только два элемента. При втором проходе шаг уменьшается, а число элементов в группе увеличивается, и при h = 1 группа включает всю последовательность целиком.
Рассмотрим процесс сортировки последовательности из 8 целых чисел при h1 = 4: 5, 6, 2, 4, 8, 3, 1, 7.
При h1 = 4 сортируются четыре группы по два элемента в каждой: 5, 8; 6, 3; 2, 1; 4, 7. В результате перестановок 6—3 и 2—1 получаем частично упорядоченную последовательность 5, 3, 1, 4, 8, 6, 2, 7. При h2= 2 сортируются две группы по четыре элемента: 5, 1, 8, 2 и 3, 4, 6, 7. В первой группе после перестановки 5—1 получим 1, 5, 8, 2, затем включение 2 в упорядоченную часть приведет к сдвигам 8 и 5: 1, 2, 5, 8. Поскольку вторая группа упорядочена, то последовательность примет вид: 1, 3, 2, 4, 5, 6, 8, 7. Сортировка с шагом h3 = 1 приводит к окончательному результату: 1, 2, 3, 4, 5, 6, 7, 8.
Рассмотрим пример.
Пример.
/* СОРТИРОВКА МЕТОДОМ ШЕЛЛА */
#include
#define n 15
int A[n]={12,3,14,15,6,1,7,8,9,5,11,2,13,4,10};
int main()
{ void Shell(int A[],int nn);
int j;
printf("\n Исходный массив: \n");
printf("\t");
for (j=0; j<n;j++)
printf("%d”,A[j]);
printf("\n Отладочная печать по шагам сортировки");
Shell(A,n);
printf("\n Отсортированный массив :\n");
for (j=0; j<n;j++)
printf("%d”,A[j]);
printf("\n");
getch(); return 0;
}
/* ФУНКЦИЯ СОРТИРОВКИ МЕТОДОМ ШЕЛЛА*/
void Shell(int A[],int nn)
{ int i,j,k,x;
k=(nn+1)/2;
while (k )
{
for (i=k; i<nn; i++)
{ if (A[i-k] > А[i])
{ x=A[i]; j=i-k;
M: A[j+k]=A[j];
if (j>k)
{ if (A[j-k] > x)
{j=j-k;
goto M;
}
}
А[j]=х;
}
}
/* Отладочная печать */
printf(" \nk=%d ",k);
for (i=0; i<nn;i++)
printf(" %d",A[i]);
if (k>2)
k=(k+1)/2;
else
k=k/2;
}
}
Исходный массив:
12 3 14 15 6 1 7 8 9 5 11 2 13 4 10.
Отладочная печать по шагам сортировки:
k = 8 9 3 11 2 6 1 7 8 12 5 14 15 13 4 10
k = 4 6 1 7 2 9 3 10 8 12 4 11 15 13 5 14
k = 2 6 1 7 2 9 3 10 4 11 5 12 8 13 15 14
k = 1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
Отсортированный массив:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15.
[Оглавление] | [<<страница] | [>>страница] | [В начало ] |