Лабораторная работа №1 Вариант 17
.doc
ФЕДЕРАЛЬНОЕ АГЕНТСТВО ПО ОБРАЗОВАНИЮ
ГОСУДАРСТВЕННОЕ ОБРАЗОВАТЕЛЬНОЕ УЧРЕЖДЕНИЕ
ВЫСШЕГО ПРОФЕССИОНАЛЬНОГО ОБРАЗОВАНИЯ
ЛИПЕЦКИЙ ГОСУДАРСТВЕННЫЙ ТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ
КАФЕДРА АВТОМАТИЗИРОВАННЫХ СИСТЕМ УПРАВЛЕНИЯ
Лабораторная работа №1
по дисциплине
«Технология программирования»
на тему:
«Программирование алгоритмов сортировки»
|
Студент |
|
|
|
Понарьин С.Н. |
|
||||||||
|
|
|
подпись, дата |
|
фамилия, инициалы |
|
||||||||
|
Группа |
|
АС-09 |
|
|
|
|
|||||||
|
|
|
|
|
|
|
||||||||
|
Принял |
|
|
|
Домашнев П.А. |
|
||||||||
|
|
|
|
|
|
|
||||||||
|
ученая степень, звание |
|
подпись, дата |
|
фамилия, инициалы |
|
Липецк 2010
1. Задание
Осуществить программную реализацию сортировки информации заданного вида сбалансированным N-ленточным слиянием (в оперативной памяти), используя выбранные, в соответствии с вариантом, из табл. 1 алгоритм внутренней сортировки и формат исходных данных.
Вариант |
ключ |
Запись 0 – только ключ, 1 – ключ и другие данные различных типов |
Метод внутренней сортировки |
17 |
сhar |
1, char[], int |
5 |
Метод Шелла (5)
Представляет собой модификацию метода вставок. Используются сравнения и перестановки элементов, но в отличие от метода вставок, в сравнении участвуют не соседние, а отстоящие друг от друга на определенном расстоянии элементы. При необходимости перестановки, элементы перемещаются скачком на данное расстояние, а не на одну позицию.
В одной из модификаций метода (в случае, предложенном Д. Шеллом) шаг кратен степеням двойки. Вначале последовательность из N элементов делится на N/2 групп, если N – четно, и на (N-1)/2 групп, если N – нечетно. Каждая группа содержит по два элемента, если количество элементов было нечетным, одна из групп содержит три элемента. Элементы каждой группы отстоят друг от друга на расстоянии N/2 или (N-1)/2. В течение первого прохода осуществляется упорядочение элементов каждой группы методом вставок. Для осуществления следующего прохода шаг уменьшается вдвое (как и число групп), по отношению к предыдущему шагу (у дробных чисел берется целая часть). Процесс повторяется до тех пор, пока шаг не станет равным единице. В этом случае методом вставок сортируется весь список (одна группа). С точки зрения программной реализации потребуется неоднократный вызов сортировки вставками с указанием, в качестве параметров (помимо исходного списка и числа элементов), индекса начального элемента группы и шага. Приблизительное число сравнений составляет N log2 N.
2. Блок-схема программы
3. Листинг программы
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>
#include <locale.h>
void main()
{
int *c,*c2,i,j,k,d,f,t,kol_sym,r,q,*lent,N;
char *a,*a2,**b,**b2,s,el,str[25]="";
setlocale(LC_ALL,"Russian");
printf("Введите число лент: ");
scanf("%d",&N);
printf("Введите количество элементов, кратное %d: ",N);
scanf("%d",&kol_sym);
lent=(int*)(malloc(N*(sizeof(int))));//Выделение памяти под считчики лент
//Выделение памяти под элементы полей
a=(char*)(malloc (kol_sym*(sizeof(char))));
b=(char**)(malloc (kol_sym*(sizeof(char))));
for(i=0;i<kol_sym;i++)
b[i]=(char*)malloc(10*sizeof(char));
b2=(char**)(malloc (kol_sym*(sizeof(char))));
for(i=0;i<kol_sym;i++)
b2[i]=(char*)malloc(10*sizeof(char));
c=(int*)(malloc(kol_sym*(sizeof(int))));
c2=(int*)(malloc(kol_sym*(sizeof(int))));
a2=(char*)(malloc (kol_sym*(sizeof(char))));
//Ввод ключевого поля
for(i=0;i<kol_sym;i++)
{
printf("\nВведите символ%d: ",i+1);
s=getch();
if((s>=65)&&(s<=122))
{
printf("%c",s);
a[i]=s;
}
else
{
printf("Некооректный символ, придется повторить");
i--;
}
}
printf("\n\n");
//Ввод строк
for(i=0;i<kol_sym;i++)
{
printf("Введите строку %d: ",i+1);
scanf("%s",b[i]);
}
printf("\n");
//Ввод числовых данных
for(i=0;i<kol_sym;i++)
{
printf("Введите число %d: ",i+1);
scanf("%d",&c[i]);
}
//Сортировка каждой ленты методом Шелла
for(r=1;r<=N;r++)
{
d=kol_sym/(N*2);//Шаг сортировки равен: длина ленты/2
while(d>0)
{
for(j=(d+(r-1)*kol_sym/N);j<(r*kol_sym/N);j++)
{
for(t=0;t<25;t++)
b2[0][t]=b[j][t];
f=a[j];
q=c[j];
for(k=j-d;f<a[k]&&k>=(r-1)*kol_sym/N;k=k-d)
{
for(t=0;t<25;t++)
b[k+d][t]=b[k][t];
a[k+d]=a[k];
c[k+d]=c[k];
}
for(t=0;t<25;t++)
b[k+d][t]=b2[0][t];
a[k+d]=f;
c[k+d]=q;
}
d=d/2;//Уменьшить шаг на 2
}
}
//Метод слияния лент
printf("\n\n");
for(i=0;i<N;i++)
lent[i]=i*kol_sym/N;//Счетчик каждой ленты
for(i=0;i<kol_sym;i++)
{
el='z';
for(j=0;j<N;j++)
if((el>=a[lent[j]])&&(lent[j]!=-1))
{
el=a[lent[j]];
d=j;
}
a2[i]=a[lent[d]];
c2[i]=c[lent[d]];
for(j=0;j<25;j++)
b2[i][j]=b[lent[d]][j];
lent[d]++;
if(lent[d]==(d*kol_sym/N)+kol_sym/N)//если счетчик достиг предела
lent[d]=-1;
}
printf("\nРезультат:\n");
for(i=0;i<kol_sym;i++)
{
printf("\n%d: %2c",i+1,a2[i]);
printf("%12s ",b2[i]);
printf("%10d ",c2[i]);
}
getch();
}
4. Контрольный пример