Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ЛР ИТ №09.doc
Скачиваний:
8
Добавлен:
16.05.2015
Размер:
94.21 Кб
Скачать

12

Государственное образовательное учреждение высшего профессионального образования

«Брянская государственная инженерно-технологическая академия»

Кафедра «Информационные технологии»

Утверждены научно-методическим

советом БГИТА

протокол №_ от «__» ____________2007 года

ИНФОРМАЦИОННЫЕ ТЕХНОЛОГИИ

Методические указания к выполнению лабораторной работы № 9 студентами, обучающимися по направлению _______ - "Информационные системы и технологии"

Брянск 2007

УДК 681.332

Информационные технологии: Методические указания к выполнению лабораторной работы № 9 студентами II курса специальности _________ - «Информационные системы и технологии»/ Брянск. гос. технол. акад. Сост. К.В. Шевченко. ‑ Брянск: БГИТА, 2007.- 12с.

Даны методические указания по выполнению лабораторной работы № 9 «Сортировка элементов массива».

Для студентов очной формы обучения.

Рецензент:

кандидат техн. наук, профессор Евельсон Л.И.

Рекомендованы редакционно-издательской и методической комиссиями механико-технологического факультета БГИТА.

Протокол № __ от __________ 2007 г

  1. Цели и задачи лабораторной работы

Целями данной лабораторной работы являются:

  1. Получение навыков сортировки двумерных массивов;

  2. Ознакомление с работой функции сортировки qsort;

  3. Ознакомление с работой функции бинарного поиска bsearch.

Продолжительность работы:

  1. самостоятельная работа – 4 часа;

  2. работа на ПЭВМ – 4 часа.

  1. Основные Сведения

    1. Методы сортировки массивов

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

Простейшим методом сортировки является «метод пузырька», который моделирует «всплывание» наибольших или наименьших элементов в конец массива. Более сложными методами являются метод перестановок и «метод Шелла». Рассмотрим их на примере одномерного массива.

Метод «пузырька» реализуется с помощью следующей последовательности действий: в массиве производится сравнение соседних элементов и если они расположены в порядке, обратном требуемому, то их меняют местами. Сортировку по возрастанию можно реализовать с помощью следующего кода.

int V[100],i,j;

for(i=0;i<100;i++)

{

for(j=1;j<100-i;j++)

{

if(V[j]<V[j-1])

{

double temp = V[j];

V[j]=V[j-1];

V[j-1]=temp;

}

}

}

В этом коде учтено, что в конце массива элементы расположены в требуемом порядке, а, следовательно, их сортировать не нужно.

Метод Шелла использует сравнение элементов из интервалов равной величины. Размер интервалов постепенно уменьшается до 1, что позволяет произвести сравнение рядом стоящих элементов. Для реализации алгоритма Шелла используют следующий код:

int V[100],i,j;

int a,gap;

for(gap=100>>1;gap>0;gap>>=1)

{

for(i=gap;i<100;i++)

for(j=i-gap;j>=0;j-=gap)

{

if(V[j]<=V[j+gap])

break;

a = V[j];

V[j] = V[j+gap];

V[j+gap] = a;

}

}

Метод Шелла может быть реализован и на другой последовательности изменения переменной gap. Требованиями к этой последовательности являются: убывание и равенство 1 последнего члена. Например, подходит следующая последовательность: 9, 5, 3, 2, 1. В примере реализована простейшая последовательность, основанная на величине сортируемого массива. Каждый последующий член последовательности в 2 раза меньше предыдущего.

Представленные фрагменты содержат несколько типичных действий:

  1. перебор элементов по определенным правилам (два или три цикла);

  2. сравнение двух элементов;

  3. обмен значениями двух элементов.

Для реализации последних двух действий чаще всего используют функции. Например:

int CmpInt(int a,int b)

{

if(a<b)

return -1;

if(a>b)

return 1;

return 0;

}

void SwapInt(int *pa, int *pb)

{

int temp = *pa;

*pa=*pb;

*pb=temp;

}

В этом случае метод пузырька может быть переписан в следующем виде:

int V[100],i,j;

for(i=0;i<100;i++)

for(j=1;j<100-i;j++)

if(CmpInt(V[j],V[j-1)<0)

SwapInt(&V[j],&V[j-1]);

Метод Шелла переписывается в виде:

int V[100],i,j;

int a,gap;

for(gap=100>>1;gap>0;gap>>=1)

for(i=gap;i<100;i++)

for(j=i-gap;j>=0;j-=gap)

{

if(CmpInt(V[j],V[j+gap])<=0)

break;

SwapInt(&V[j],&V[j+gap]);

}

}

В стандартных библиотеках языка C имеется функция быстрой сортировки, основанная на «быстром» методе. Название функции qsort (от quick sort). Для работы с этой функцией необходимо описать процедуру сравнения двух элементов массива. Для того чтобы сортировка могла работать с произвольными данными используются указатели на void.

Прототип функции qsort имеет вид:

void qsort(

void *base, //адрес первого элемента массива

size_t nelem, //количество элементов

size_t width, //размер одного элемента

int (*fcmp)(const void *, const void *)

);

Последний аргумент – указатель на функцию сравнения.

Перепишем функцию сравнения элементов:

int Compare(const void *elem1,const void *elem2)

{

if(*(int*)elem1 > *(int*)elem2) return 1;

if(*(int*)elem1 < *(int*)elem2) return -1;

return 0;

// в данном случае это можно сократить до следующего кода

// return *(int*)elem1 - *(int*)elem2;

}

Сортировка осуществляется с помощью следующего кода:

int V[100],i,j;

qsort(V, N, sizeof(V[0]), Compare);

При написании функции все приведения к нужной структуре данных производятся программистом, в данном примере производится приведение к типу int.

При сортировке информации о каких-либо «объектах» (в данной работе – точках) необходимо учитывать то, что информация связана между собой. В силу этого проверки должны происходить не порознь, а совместно. Сравнивать два объекта можно с помощью: последовательной проверки «полей». Если значения отличаются, то возвращается признак отличия (+1 – если значение поля первого элемента больше значения поля второго элемента, -1 – если значение поля первого элемента меньше значения поля второго элемента). Если же значения полей равны, то переходят к следующим полям. Последовательность полей может быть произвольной. Например, при сортировке массива содержащего информацию о номерах и координатах точек она может быть следующей X-Y-Z-N (что будет соответствовать полям с индексами 1, 2, 3, 0 (если последовательность хранения N-X-Y-Z)) или Y-X-Z-N (2, 1, 3, 0).

При реализации данного подхода удобно использовать проверку в цикле с введением дополнительного массива индексов.

int Cmp(const void *e1,const void *e2)

{

int index[4]={1,2,3,0};

int i;

int *element_1 = (int*) e1;

int *element_2 = (int*) e2;

for(i=0;i<4;i++)

{

if(elemnt_1[index[i]] > elemnt_2[index[i]]) return 1;

if(elemnt_1[index[i]] < elemnt_2[index[i]]) return -1;

}

return 0;

}