Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Моя реализация быстрой сортировки и qsort. Язык С

44K
04 декабря 2009 года
Bonez92
37 / / 25.08.2009
Проблема: Вот код:
Код:
#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;
}

В этом коде моей реализацией быстрой сортировки является mysort(...). Так вот моя реализация сортирует массив размером 10 миллионов за 11 секунд, а qsort - за 2. Такой результат не удовлетворителен.

Вопрос: Скажите пожалуйста, как можно оптимизировать мою функцию?
5
04 декабря 2009 года
hardcase
4.5K / / 09.08.2005
Цитата: Bonez92
Скажите пожалуйста, как можно оптимизировать мою функцию?


Посмотреть исходники qsort ?

14
04 декабря 2009 года
Phodopus
3.3K / / 19.06.2008
Че у вас за mysort то такой сумасшедший? qsort по сути строчек 10-15 занимает.
12K
05 декабря 2009 года
Ghox
297 / / 26.07.2009
Цитата: hardcase
Посмотреть исходники qsort ?


Например, здесь:
http://www.jbox.dk/sanos/source/lib/qsort.c.html

Цитата: Phodopus
Че у вас за mysort то такой сумасшедший? qsort по сути строчек 10-15 занимает.


Ну, все-таки побольше...

412
07 декабря 2009 года
grgdvo
323 / / 04.07.2007
Воспользуйтесь профилировщиком. Сдается мне, что функция calloc не слабо времени отнимает.
44K
09 декабря 2009 года
Bonez92
37 / / 25.08.2009
Готовую реализацию взял сдесь: http://algolist.manual.ru/sort/quick_sort.php
Код:
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);
}


Но у меня возник вопрос - почему в объявлении должно быть j=size, а не size-1.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог