
- •Структурное программирование и оформление программ
- •Теоретические сведения
- •Структурное программирование
- •Оформление программ
- •Отладка и тестирование программ
- •Задание к работе
- •Пример построения цикла
- •Определения элементов цикла
- •Пример формального построения цикла
- •Задание к работе
- •Содержание отчета
- •Контрольные вопросы
- •Алгоритмы сортировки
- •Теоретические сведения
- •Задача сортировки
- •Реализация простейшего алгоритма сортировки
- •Сложный алгоритм сортировки
- •Задание к работе
- •Содержание отчета
- •Контрольные вопросы
- •Приложение
Алгоритмы сортировки
Цель работы: отработка навыков построения вложенных циклов, изучение алгоритмов сортировки, освоение методов структурной разработки программ и тестирования.
Теоретические сведения
Задача сортировки
Имеется массив целых чисел, расположенных в произвольном порядке. Необходимо расположить числа в этом массиве в порядке возрастания, т. е. любой элемент должен быть не меньше предыдущего.
Решение задачи довольно легко осуществляется в рекуррентной форме: находим наименьший элемент, располагаем его в первой позиции. Повторяем эту же процедуру для остальных элементов.
Задачу нахождения наименьшего элемента также легко решить в рекуррентной форме: берем первые два элемента, из них выбираем меньший, этот элемент по очереди сравниваем с остальными элементами.
Нужно преобразовать два описанных рекуррентных решения в цикл. Эти преобразования можно произвести, используя алгоритм построения цикла, рассмотренный в лабораторной работе 2.
Реализация простейшего алгоритма сортировки
Построим внешний цикл программы сортировки.
На каждом шагу цикла мы будет находить один наименьший элемент и располагать его на нужной позиции. Обозначим t номер шага. После каждого шага мы будем иметь t отсортированных (расположенных на своих местах) элементов. Это можно обозначить так: {a0 > a1 > … > at – 1, at … an – 1}. В этой записи используются фигурные скобки. Такими скобками обычно отмечают условия выполнения (инвариант, предусловие, постусловие) в тексте программы.
Предусловие этого цикла: t = 0. При этом нет ни одного отсортированного элемента.
Если отсортированы все элементы кроме одного, то последний элемент автоматически располагается на последней позиции. Тогда условие окончания этого цикла таково: t = n – 1, при этом все элементы будут отсортированы, иначе цикл будет продолжаться, пока не будет достигнуто, что t < n – 1.
В теле цикла необходимо увеличить t на единицу, при этом должен сохраниться инвариант – элементы от 0 до t’ – 1 должны находиться на нужных местах. Поскольку до этого на нужных местах были расположены элементы от 0 до t – 1 = t’ – 2, то достаточно найти наименьший элемент среди элементов от t’ – 1 до n – 1 и поменять его местами с элементом t’ – 1 или найти наименьший элемент от t до n – 1 и поменять его с элементом t. Использование старого значения t удобнее, поскольку не требует дополнительных вычитаний 1 и позволяет вычислить новое значение t в конце тела (записать вычисление t в шаг цикла оператора for). Построим цикл, который находит наименьший среди элементов от t до n – 1.
На каждом шаге этого цикла будет добавляться по одному элементу к множеству элементов, для которых известен минимальный из них. Другими словами, инвариантом системы будет условие о том, что известен наименьший элемент среди элементов от t до j – 1, где j – переменная цикла. Обозначим mi индекс этого наименьшего элемента, а m – его значение.
На первом этапе работы цикла множество будет состоять из одного элемента, который, поскольку он один, будет наименьшим элементом этого множества, т. е. j = t + 1, mi = t, m = at. Это предусловие цикла, его выполнения необходимо достичь при инициализации.
Очевидно, что условием выполнения внутреннего цикла будет j < n.
В
теле цикла j
должно
увеличиться на единицу. Для того чтобы
сохранился инвариант, достаточно
проверить, меньше ли элемент
переменной m,
и если меньше, то изменить m
и m
– i.
Осталось уточнить, как поменять элементы в конце внешнего цикла. С этим предлагается разобраться самостоятельно по приведенному ниже коду.
void print_mas(int* m, int n)
{
int i;
for(i=0;i<n;i++)
printf("%i ", m[i]);
printf("\n");
}
int main()
{
int a[8]={1,2,4,3,8,7,5,6};
int j, t, m, mi, n=8;
print_mas(a, n);
for(t=0; t<n-1; t++)
{
// Найти наименьший элемент
m=a[t];
mi=t;
for(j=t; j<n; j++)
if(a[j]<m) { m=a[j]; mi=j; };
// Поместить наименьший элемент на первую позицию
a[mi]=a[t]; a[t]=m;
}
print_mas(a, 8);
}