Advertisement
Bisus

Untitled

Nov 22nd, 2019
167
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.76 KB | None | 0 0
  1. // main.c
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <time.h>
  5. #include "merge_sort.h"
  6. int read_array(const char *name, double *array, int n);
  7. void rand_array(double *array, int n);
  8. void print_array(double *array, int n);
  9. int f_up(double a, double b);
  10. int f_down(double a, double b);
  11.  
  12. int f_up(double a, double b)
  13. {
  14.     if( a>b )
  15.         return 1;
  16.  
  17.     if( a<b )
  18.         return -1;
  19.  
  20.     return 0;
  21. }
  22.  
  23. int f_down(double a, double b)
  24. {
  25.     if( a>b )
  26.         return -1;
  27.  
  28.     if( a<b )
  29.         return 1;
  30.  
  31.     return 0;
  32. }
  33.  
  34. /* Предполагается, что n>0 и по указателю array выделена память для n элементов.
  35.  * Ф-ия возвращает:
  36.  * -2, если не удалось прочитать элемент;
  37.  * -1, если не удалось открыть файл;
  38.  * 0, в случае успешного завершения.
  39.  * */
  40. int read_array(const char *name, double *array, int n)
  41. {
  42.     FILE *input;
  43.     int i;
  44.  
  45.     if( !(input = fopen(name, "r")) )
  46.         return -1;
  47.  
  48.     for( i = 0; i<n; i++ )
  49.     {
  50.         if( fscanf(input, "%lf", array + i)!=1 )
  51.         {
  52.             fclose(input);
  53.             return -2;
  54.         }
  55.     }
  56.  
  57.     fclose(input);
  58.     return 0;
  59. }
  60.  
  61. /* Предполагается, что n>0 и по указателю array выделена память для n элементов. */
  62. void rand_array(double *array, int n)
  63. {
  64.     int i;
  65.  
  66.     for( i = 0; i<n; i++ )
  67.         array[i] = rand();
  68. }
  69.  
  70. /* Предполагается, что n>0 и по указателю array выделена память для n элементов.
  71.  * */
  72. void print_array(double *array, int n)
  73. {
  74.     int i;
  75.  
  76.     if( n>20 )
  77.         n = 20;
  78.  
  79.     for( i = 0; i<n; i++ )
  80.         printf("Array[%d]=%lf\n", i, array[i]);
  81. }
  82.  
  83. int main(int argc, const char *argv[])
  84. {
  85.     int n, result_read;
  86.     double *a, *b;
  87.     clock_t time_begin;
  88.  
  89.     if( ((argc!=2) && (argc!=3)) || (sscanf(argv[1], "%d", &n)!=1) || (n<=0) )
  90.     {
  91.         fprintf(stderr, "Usage: %s size_of_array [file_with_array]\t\t([size_of_array]>0)\t(array is random if no file_with_array)\n", argv[0]);
  92.         return 1;
  93.     }
  94.  
  95.     if( !(a = (double *)malloc(n*sizeof(double))) )
  96.     {
  97.         fprintf(stderr, "Can not allocate memory!\n");
  98.         return 2;
  99.     }
  100.     if( !(b = (double *)malloc(n*sizeof(double))) )
  101.     {
  102.         fprintf(stderr, "Can not allocate memory!\n");
  103.         free(a);
  104.         return 2;
  105.     }
  106.     // Память выделена
  107.  
  108.     if( argc==3 )
  109.     {
  110.         result_read = read_array(argv[2], a, n);
  111.         if( result_read<0 )
  112.         {
  113.             switch( result_read )
  114.             {
  115.             case -2:
  116.                 fprintf(stderr, "Can not read element from %s\n", argv[2]);
  117.                 break;
  118.             case -1:
  119.                 fprintf(stderr, "Can not open file %s\n", argv[2]);
  120.                 break;
  121.             default:
  122.                 fprintf(stderr, "Unknown error %d in file %s\n", result_read, argv[2]);
  123.             }
  124.  
  125.             free(a);
  126.             free(b);
  127.             return 3;
  128.         }
  129.     } else
  130.     {
  131.         rand_array(a, n);
  132.     }
  133.     // Массив считан или сгенерирован случайный
  134.  
  135.     printf("Array a[]:\n");
  136.     print_array(a, n);
  137.  
  138.     time_begin = clock();
  139.     merge_sort(a, b, n, &f_up);
  140.     printf("Time: %.2f seconds\nArray b[]:\n", (float)( clock() - time_begin )/CLOCKS_PER_SEC);
  141.     print_array(b, n);
  142.  
  143.     free(a);
  144.     free(b);
  145.     return 0;
  146. }
  147.  
  148.  
  149.  
  150. // merge_sort.h
  151. #ifndef MERGE_SORT_H
  152. #define MERGE_SORT_H
  153.  
  154. void merge_sort(double *a, double *b, int n, int (*p)(double, double));
  155.  
  156. #endif
  157.  
  158.  
  159.  
  160. // merge_sort.c
  161. #include "merge_sort.h"
  162. void merge(double *a, double *b, double *c, int n, int m, int (*p)(double, double));
  163.  
  164. /* Предполагается, что n>0, и по указателю a расположен массив из n элементов.
  165.  * Сортировка Неймана.
  166.  * */
  167. void merge_sort(double *a, double *b, int n, int (*p)(double, double))
  168. {
  169.     int i, size, num;
  170.  
  171.     for( size = 1; size<=(int)(n/2); size *= 2 )// Размер группы
  172.     {
  173.         for( num = 0; num<=(int)(n/size) - 2; num += 2 )// Номер группы
  174.         {
  175.             merge(a + num*size, a + (num + 1)*size, b, size, size, p);
  176.             for( i = 0; i<2*size; i++ )
  177.             {
  178.                 a[i + num*size] = b[i];
  179.             }
  180.         }
  181.     }
  182.  
  183.     merge(a, a + size, b, size, n - size, p);
  184. }
  185.  
  186. /* Предполагается, что n>0, m>0 и по указателю a записан неубывающий массив длины n, по указателю b неубывающий массив из m элементов,
  187.  * по указателю c выделена память для (n + m) элементов.
  188.  * Ф-ия строит неубывающий массив слиянием a и b.
  189.  * */
  190. void merge(double *a, double *b, double *c, int n, int m, int (*p)(double, double))
  191. {
  192.     int i = 0, j = 0, k;
  193.  
  194.     for( k = 0; (i<n) && (j<m); k++ )
  195.     {
  196.         if( p(b[j], a[i])>0 )
  197.         {
  198.             c[k] = a[i];
  199.             i++;
  200.         } else
  201.         {
  202.             c[k] = b[j];
  203.             j++;
  204.         }
  205.     }
  206.  
  207.     for( ; i<n; k++, i++ )
  208.         c[k] = a[i];
  209.  
  210.     for( ; j<m; k++, j++)
  211.         c[k] = b[j];
  212. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement