#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <time.h>
// Функция для перестановки
int exchange(double& param1, double& param2, int sorttype)
{
double d_temp;
if (sorttype==1)
{
// Если последовательность должна возрасать ...
if (param1>param2)
{
// Если левый элемент больше правого ...
d_temp = param1;
param1 = param2;
param2 = d_temp;
return 1;
}
} else {
// Если последовательность должна убывать ...
if (param1<param2)
{
// Если левый элемент меньше правого ...
d_temp = param1;
param1 = param2;
param2 = d_temp;
return 1;
}
}
return 0;
}
int mysort(double m[], int size, int sorttype)
{
unsigned int i, // Присвоить значение левому указателю
j, // Присвоить значение правому указателю
k=0, // Индекс массива подгрупп
d=1,
flag=0, // Флаг четности обмена, 0 - обмен новый
npg=0;
int size_pg;
size_pg=size;
unsigned int *pg_current_l, // Массив левых индексов подгрупп
*pg_current_r; // Массив правых индексов подгрупп
// Выделить память для массива левых индексов подгрупп
pg_current_l = (unsigned int*)calloc(size_pg,sizeof(unsigned int));
pg_current_r = (unsigned int*)calloc(size_pg,sizeof(unsigned int));
// Подготовить первые левые и правые индексы
pg_current_l[0]=0;
pg_current_r[0]=size-1;
// Здесь уже оно
while (npg>=k)
{
i=pg_current_l[k];
j=pg_current_r[k];
while (i!=j)
{
// Поменяли ли их или нет?...
if (exchange(m, m[j], sorttype)==0)
{
if (flag==1) i++;
else j--;
} else {
if (flag==0)
{
i++;
flag=1; //Установка флага для последующего перемещения левого индекса вправо (до следующего обмена)
} else {
j--;
flag=0; //Установка флага для последующего перемещения правого индекса влево
}
}
}
if (i!=pg_current_l[k])
{
// Если текущий индекс не является крайней левой...
pg_current_l[k+d]=pg_current_l[k];
pg_current_r[k+d]=i-1;
d++;
npg++;
}
if (i!=pg_current_r[k])
{
// Если текущий индекс не является крайней левой...
pg_current_l[k+d]=i+1;
pg_current_r[k+d]=pg_current_r[k];
d++;
npg++;
}
k++;
d--;
}
free(pg_current_l);
free(pg_current_r);
return 0;
}
int qsort_compare_1 (const void * a, const void * b)
{
if (*(double*)a > *(double*)b) return 1;
if (*(double*)a < *(double*)b) return -1;
return 0;
}
int qsort_compare_2 (const void * a, const void * b)
{
if (*(double*)a > *(double*)b) return -1;
if (*(double*)a < *(double*)b) return 1;
return 0;
}
int main()
{
double d_temp, // Временная переменная
*m, // Наш массив (для моей сортировки)
*m0, // Наш массив (для сортировки qsort)
time_elapsed_my_sa[7], // Среднее потраченое время за сортровку (для задания №2)
time_elapsed_qs_sa[7]; // --//--
unsigned size, // Размер массива
prevsize, // Размер предыдущего массива
suposize, // Размер массива, с которым массив сортируется от 55 до 65 секунд
sorttype, // Типа сортировки
i,j,k, // Счетчики
enouph=0, // Флаг достаточности и не только
interval_found=0, // Флаг для интервала
klop[]={1, 2, 5, 10, 50, 100, 1000};
clock_t time_elapsed;
int (*qc)(const void *, const void *); // Указатель на функцию сравнения для кусорта
printf ("Programma sortirovki\n\n");
// Приглашение ввести размерность массива
printf ("Vvedite razmernost' massiva:");
scanf ("%lf", &d_temp);
// Проверка введенных данных
while ((d_temp<1) || (fabs(d_temp-ceil(d_temp))>1.e-32))
{
printf ("Vvedite razmernost' massiva:");
scanf ("%lf", &d_temp);
}
size=(int)d_temp;
// Если размерность массива равен 1
if (size==1)
{
printf ("Oshibka: sortirovat' nechego\n");
return 0;
}
// Вывод меню
printf ("Tipy sortirovki:\n");
printf ("1. Po vozrastaniju;\n");
printf ("2. Po ubyvaniju;\n");
// Приглашение ввести пункт меню
printf ("Vvedite tip sortirovki po nomeru:");
scanf ("%lf", &d_temp);
// Проверка введенных данных
while ((d_temp<1) || (d_temp>2) || (fabs(d_temp-ceil(d_temp))>1.e-32))
{
printf ("Vvedite tip sortirovki po nomeru:");
scanf ("%lf", &d_temp);
}
sorttype=(int)d_temp;
// Присвоение указателя на функцию (для кусорт)
if (sorttype==1)
{
qc = qsort_compare_1;
} else {
qc = qsort_compare_2;
}
// Выдиление динамической памяти для массива
m=(double*)malloc(size*sizeof(double));
m0=(double*)malloc(size*sizeof(double));
// Инициализация генератора случайных чисел
srand((unsigned)time(NULL));
// Наполнение динамической памяти элементами (от -10 до 10) и выводы их значений
for (i=0; i<size; i++)
{
m=(double)rand()/(RAND_MAX+1)*20-10;
m0=m;
if (size<100) printf ("m[%d]=%lf\n", i, m);
}
//
// Задание №0. Сортировка (мусорт и кусорт), замер времени, проверка правильности
//
//Сортировка по мусорт
time_elapsed = clock();
mysort(m, size, sorttype);
time_elapsed = (clock() - time_elapsed);
printf ("\n");
// Вывод результата
if (size<100)
{
for (i=0; i<size; i++) printf ("m[%d]=%lf\n", i, m);
}
// Вывод времени сотрировки
printf ("Array sorted using my method in ~%d milliseconds\n", (int)(time_elapsed));
// Проверка правильности
for (i=1; i<size; i++)
{
if (sorttype==1)
{
if (m<m[i-1])
{
printf ("mysort sovershil nevernuyu sortirovku (m[%d]<[%d])\n", i, i-1);
return 0;
}
} else {
if (m>m[i-1])
{
printf ("mysort sovershil nevernuyu sortirovku (m[%d]>[%d])", i, i-1);
return 0;
}
}
}
printf ("mysort sovershil vernuyu sortirovku\n");
free(m);
//Сортировка по кусорт
time_elapsed = clock();
qsort(m0, size, sizeof(double), qc);
time_elapsed = (clock() - time_elapsed);
printf ("\n");
// Вывод результата
if (size<100)
{
for (i=0; i<size; i++) printf ("m[%d]=%lf\n", i, m0);
}
// Вывод времени сотрировки
printf ("Array sorted using qsort in ~%d milliseconds\n", (int)(time_elapsed));
// Проверка правильности
for (i=1; i<size; i++)
{
if (sorttype==1)
{
if (m0<m0[i-1])
{
printf ("qsort sovershil nevernuyu sortirovku (m[%d]<[%d])\n", i, i-1);
return 0;
}
} else {
if (m0>m0[i-1])
{
printf ("qsort sovershil nevernuyu sortirovku (m[%d]>[%d])\n", i, i-1);
return 0;
}
}
}
printf ("qsort sovershil vernuyu sortirovku\n");
free(m0);
return 0;
}
Моя реализация быстрой сортировки и qsort. Язык С
Код:
В этом коде моей реализацией быстрой сортировки является mysort(...). Так вот моя реализация сортирует массив размером 10 миллионов за 11 секунд, а qsort - за 2. Такой результат не удовлетворителен.
Вопрос: Скажите пожалуйста, как можно оптимизировать мою функцию?
Цитата: Bonez92
Скажите пожалуйста, как можно оптимизировать мою функцию?
Посмотреть исходники qsort ?
Че у вас за mysort то такой сумасшедший? qsort по сути строчек 10-15 занимает.
Цитата: hardcase
Посмотреть исходники qsort ?
Например, здесь:
http://www.jbox.dk/sanos/source/lib/qsort.c.html
Цитата: Phodopus
Че у вас за mysort то такой сумасшедший? qsort по сути строчек 10-15 занимает.
Ну, все-таки побольше...
Воспользуйтесь профилировщиком. Сдается мне, что функция calloc не слабо времени отнимает.
http://algolist.manual.ru/sort/quick_sort.php
Но у меня возник вопрос - почему в объявлении должно быть j=size, а не size-1.
Готовую реализацию взял сдесь:
Код:
void mysort(double *a, unsigned long size, int sorttype)
{
// На входе - массив a[], a[N] - его последний элемент.
long i = 0, j = size; // поставить указатели на исходные места
double temp, p;
p = a[ size>>1 ]; // центральный элемент
// процедура разделения
do {
while ( a < p ) i++;
while ( a[j] > p ) j--;
if (i <= j) {
temp = a; a = a[j]; a[j] = temp;
i++; j--;
}
} while ( i<=j );
// рекурсивные вызовы, если есть, что сортировать
if ( j > 0 ) mysort(a, j, sorttype);
if ( size > i ) mysort(a+i, size-i, sorttype);
}
{
// На входе - массив a[], a[N] - его последний элемент.
long i = 0, j = size; // поставить указатели на исходные места
double temp, p;
p = a[ size>>1 ]; // центральный элемент
// процедура разделения
do {
while ( a < p ) i++;
while ( a[j] > p ) j--;
if (i <= j) {
temp = a; a = a[j]; a[j] = temp;
i++; j--;
}
} while ( i<=j );
// рекурсивные вызовы, если есть, что сортировать
if ( j > 0 ) mysort(a, j, sorttype);
if ( size > i ) mysort(a+i, size-i, sorttype);
}
Но у меня возник вопрос - почему в объявлении должно быть j=size, а не size-1.