СОРТИРОВКА ДАННЫХ
[Оглавление] [<< страница] [>>страница]


   2.1. Сортировка методом прямого включения
 

Пусть имеется последовательность элементов а0, а1, a2, ..., аn-1. Эта последовательность мысленно делится на две последовательности: упорядоченную последоваельность а0, а1, ....,ai-1 и исходную, неупорядоченную ai, ai+1, ..., an-1. Очевидно, что первоначально упорядоченная последовательность состоит из единственного элемента а0. При каждом шаге, начиная с i = 1 и увеличивая i каждый раз на единицу, из исходной последовательности извлекается i-й элемент аi, и вставляется в готовую последовательность в нужное место, при необходимости сдвигая элементы готовой последовательности на одну позицию вправо вплоть i-й позиции. Поиск подходящего места осуществляется сравнением аi, с элементами aj, j=i-1, i-2, ..., 0, и одновременным обменом местами аi, и cj, если аi<aj, т.е. сдвигом aj на одну позицию вправо. Процесс поиска заканчивается при выполнении одного из условий:

Этот метод обеспечивает устойчивую сортировку.

Для процедуры сортировки методом прямого включения число сравнений С и число пересылок М таковы: Cm,n = n-1; Ссредн = (n2 + n - 2)/4; Сmах = (n2 - n)/2 - 1; Mmin = 2(n - 1); Мсредн= (n2+ 9n - 10)/4; Мmах = (n2 + Зn - 4)/2.

Рассмотрим пример программы сортировки методом прямого включения.
Пример.

/* СОРТИРОВКА МЕТОДОМ ПРЯМОГО ВКЛЮЧЕНИЯ */
#include
#define n 8
int A[n]={27,412,71,81,59,14,273,87};
main()
{ void Sis(int A[],int nn);
int j;
printf("\n Исходный массив: \n\t");
for (j=0; j<n; j++)
printf("%d\t",A[j]);
printf("\n");
Sis(A.n);
printf("\n Отсортированный массив :\n\f);
for (j=0; j<n; j++)
printf("%d\t",A[j]);
printf("\n");
getch(); return 0; }

/*ФУНКЦИЯ СОРТИРОВКИ ПРЯМЫМ ВКЛЮЧЕНИЕМ*/
void Sis(int A[],int nn)
{ int i,j,k;
printf("\n Отладочная печать по шагам сортировки");
for (i=1; i<nn; i++)
{k=A[i];
j=i-1;
while (k<A[j] && j >=0)
{ A[j+1]=A[j];
j--;}
/* Отладочная печать */
printf("\n i=%d",i);
for (j=0; j<nn; j++)
printf("\t%d",A[j]);
}
}

Исходный массив:
27  412   71   81   59   14   273   87
Отладочная печать по шагам сортировки:
i=1  27  412  71  81  59  14  273  87
i=2  27  71  412  81  59  14  273  87
i=3  27  71  81  412  59  14  273  87
i=4  27  59  71  81  412  14  273  87
i=5  14  27  59  71  81  412  273  87
i=6  14  27  59  71  81  273  412  87
i=7  14  27  59  71  81  87  273  412


Отсортированный массив:
14   27   59   71   81   87   273   412

Алгоритм с прямыми включениями можно легко улучшить с учетом того, что готовая последовательность, куда надо вставить новый элемент, уже упорядочена. Тогда место включения ищется методом двоичного (бинарного) поиска. Такой улучшенный алгоритм сортировки называется методом с двоичным включением (методом прямого включения с делением пополам). Однако применение этого алгоритма оправдано только тогда, когда число сортируемых элементов достаточно велико.

Среднее число сравнений здесь С = O(nlog2n), а среднее число сдвигов М = О(n2).

Пример

/* СОРТИРОВКА МЕТОДОМ ПРЯМОГО ВКЛЮЧЕНИЯ С ДЕЛЕНИЕМ ПОПО-ЛАМ */
«include
define n 8

int A[n]={27,412,71,81,59,14,273,87};
main()
{ void BinIns(int A[],int nn);
int j;
printf("\n Исходный массив \n");
for (j=0; j<n; j++)
printf("\t%d",A[j]);
printf("\n");
BinIns(A,n);
printf("\n Отсортированный массив \n");
for (j=0; j<n; j++)
printf("\t%d",A[j]);
printf("\n");
getch(); return 0;
}
/* ФУНКЦИЯ СОРТИРОВКИ ПРЯМЫМ ВКЛЮЧЕНИЕМ С ДЕЛЕНИЕМ ПОПО-ЛАМ */
void Binlns(int A[],int nn)
{ int i,j,x,m,L,R;
printf("\ Отладочная печать по шагам сортировки ");
for (i=1; i<nn; i++)
{ x=A[i]; L=0; R=i; printf("\n %d",i);
while (L<R)
{ m=(L+R)/2;
if (A[m] ≤x)
L=m+1;
else
R=m;
}
for (j=i; j≥R; j--)
A[R]=x;
/* Отладочная печать по шагам сортировки */
for (j=0; j<nn;j++)
printf("\t %d”,A[j]);
}
}

Исходный массив 27   412   71   81   59   14   273   87
Отладочная печать по шагам сортировки:

j=1   27  412  71  81  59  14  273  87
j=2   27  71  412  81  59  14  273  87
j=3   27  71  81  412  59  14  273  87
j=4   27  59  71  81  412  14  273  87
j=5   14  27  59  71  81  412  273  87
j=6   14  27  59  71  81  273  412  87
j=7   14  27  59  71  81  87  273  412
Отсортированный массив:
14   27   59   71   81   87   273   412

[Оглавление] [<<страница] [>>страница] [В начало ]