Advertisement
CherMi

Lab2

Feb 27th, 2020
255
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 13.70 KB | None | 0 0
  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include <stdio.h>
  3. #include <malloc.h>
  4. #include <math.h>
  5.  
  6. struct list //Элемент списка
  7. {
  8.     struct list *prev; //Указатель на предыдущий элемент списка (= NULL, если первый элемент)
  9.     double data; //Данные элемента
  10.     struct list *next; //Указатель на следующий элемент списка (= NULL, если последний элемент)
  11. }*ptr, *ptr1; //Указатель на начало списка
  12.  
  13. struct descriptor
  14. {
  15.     struct list *first; //Указатель на первый элемент
  16.     int N; //Кол-во элементов в списке
  17.     int list_exists; //Если 1, список существует, если 0, нет
  18. };
  19.  
  20. void ListCreation(struct descriptor *descriptor); //Подпрограмма для добавления элемента
  21. void ListOutput(struct descriptor *descriptor); //Подпрограмма для вывода списка
  22. void ListDelete(struct descriptor *descriptor); //Подпрограмма для удаления списка
  23. void ListSearchMax(struct descriptor *descriptor); //Подпрограмма для поиска индексов наибольших элементов списка
  24. void ListAddData(struct descriptor *descriptor); //Подпрограмма для добавления элемента
  25. void ListDeleteEnd(struct descriptor *descriptor); //Подпрограмма для удаления последнего элемента списка
  26.  
  27. void main()
  28. {
  29.     int key;
  30.     double temp;
  31.     struct descriptor descriptor;
  32.     descriptor.list_exists = 0;
  33.     while (1) //Цикл меню
  34.     {
  35.         printf("Choose function.\n1 - create list.\n2 - output list.\n3 - delete list.\n4 - find max.\n5 - add new data in any place.\n6 - delete last data.\n0 - exit.\nChosen function - "); //Выбор действия
  36.         scanf("%d", &key); //Ввод клавиши действия
  37.         switch (key)
  38.         {
  39.         case 1: // Создание списка
  40.         {
  41.             ListCreation(&descriptor);
  42.             break;
  43.         }
  44.         case 2: //Вывод списка на экран или в файл
  45.         {
  46.             ListOutput(&descriptor);
  47.             break;
  48.         }
  49.         case 3: //Очистка (удаление) списка
  50.         {
  51.             ListDelete(&descriptor);
  52.             break;
  53.         }
  54.         case 4: //Нахождение индексов максимальных элементов списка
  55.         {
  56.             ListSearchMax(&descriptor);
  57.             break;
  58.         }
  59.         case 5: //Добавление элемента в любое место списка
  60.         {
  61.             ListAddData(&descriptor);
  62.             break;
  63.         }
  64.         case 6: //Удаление элемента из конца списка
  65.         {
  66.             ListDeleteEnd(&descriptor);
  67.             break;
  68.         }
  69.         case 0:
  70.         {
  71.             printf("Exiting program.\n"); //Выход из программы
  72.             break;
  73.         }
  74.         default: //Если выбранной команды не существует
  75.         {
  76.             printf("This feature doesn't exist. Please try again.\n");
  77.             break;
  78.         }
  79.         }
  80.         if (key == 0)
  81.             break;
  82.     }
  83. }
  84.  
  85. void ListCreation(struct descriptor *descriptor) //Подпрограмма для создания списка
  86. {
  87.     FILE *in;
  88.     int i;
  89.     double temp;
  90.     if (descriptor->list_exists == 1) //Если список уже существует
  91.     {
  92.         printf("List is already created. Please delete it before.\n");
  93.     }
  94.     else //Создание списка в случае его отсутствия
  95.     {
  96.         in = fopen("C:\\test\\SiAODlab2Input.txt", "rt");
  97.         if (in == NULL) //Если файл открыть не удалось
  98.         {
  99.             printf("Initial file wasn't opened.\n");
  100.             return -1;
  101.         }
  102.         descriptor->N = 20; //Размер списка равен 20
  103.         struct list *ptr;
  104.         ptr = malloc(sizeof(struct list)); //Выделение памяти под первый элемент списка
  105.         descriptor->first = ptr;
  106.         ptr->prev = NULL; //Присвоение указателю на предыдущий элемент значения NULL
  107.         ptr->next = NULL; //Присвоение указателю на следующий элемент значения NULL
  108.         fscanf(in, "%lf", &temp); //Ввод элемента списка в промежуточное хранилище
  109.         ptr->data = temp; //Запись значения в список
  110.         for (i = 1; i < descriptor->N; i++)
  111.         {
  112.             ptr1 = malloc(sizeof(struct list)); //Выделение памяти под элемент списка
  113.             fscanf(in, "%lf", &temp); //Ввод элемента списка в промежуточное хранилище
  114.             ptr1->data = temp; //Запись значения в список
  115.             ptr1->prev = ptr; //Запись указателя на предыдущий (i-1) элемент
  116.             ptr1->next = NULL; //Присвоение указателю на следующий элемент значения NULL
  117.             ptr->next = ptr1; //Запись указателя на следующий элемент (производится в i-1 элементе)
  118.             ptr = ptr1;
  119.         }
  120.         fclose(in);
  121.         printf("List is successfully created.\n");
  122.         descriptor->list_exists = 1; //Перевод флага в значение "список существует"
  123.     }
  124. }
  125.  
  126. void ListOutput(struct descriptor *descriptor) //Подпрограмма для вывода списка
  127. {
  128.     int key1, i;
  129.     if (descriptor->list_exists == 0) // Если список не существует
  130.     {
  131.         printf("List doesn't exist, it's impossible to show it.\n");
  132.     }
  133.     else // Если список существует
  134.     {
  135.         printf("Choose output type.\n1 - screen.\n2 - file.\n");
  136.         scanf("%d", &key1); //Выбор вида вывода
  137.         if (key1 == 1) //Вывод списка на экран
  138.         {
  139.             ptr = descriptor->first;
  140.             for (i = 0; i < descriptor->N; i++)
  141.             {
  142.                 printf("data[%d] = %lf\n", i + 1, ptr->data); //Вывод данных на экран
  143.                 ptr = ptr->next; //Переход к следующему элементу
  144.             }
  145.         }
  146.         else if (key1 == 2) //Запись списка в файл
  147.         {
  148.             FILE *out;
  149.             out = fopen("C:\\test\\SiAODlab2Output.txt", "wt"); //Открытие файла в режиме записи для записи списка
  150.             if (out == NULL) //Если файл открыть не удалось
  151.             {
  152.                 printf("File wasn't opened.\n");
  153.             }
  154.             else //Если файл открыть удалось
  155.             {
  156.                 ptr = descriptor->first;
  157.                 for (i = 0; i < descriptor->N; i++)
  158.                 {
  159.                     fprintf(out, "%lf [%d]\n", ptr->data, i + 1); //Запись элемента списка и его индекса в файл
  160.                     ptr = ptr->next; //Переход к следующему элементу
  161.                 }
  162.                 fclose(out);
  163.             }
  164.         }
  165.         printf("Successful output.\n");
  166.     }
  167. }
  168.  
  169. void ListDelete(struct descriptor *descriptor) //Подпрограмма для удаления списка
  170. {
  171.     int i;
  172.     if (descriptor->list_exists == 0) // Если списка не существует
  173.     {
  174.         printf("List wasn't created. Please create it before.\n");
  175.     }
  176.     else //Если список существует
  177.     {
  178.         if (descriptor->N == 1) //Если один элемент
  179.         {
  180.             free(descriptor->first); //Освобождение памяти (дескриптор)
  181.         }
  182.         else if (descriptor->N == 2) //Если два элемента
  183.         {
  184.             ptr1 = descriptor->first->next; //Указатель ptr1 на 2-ой элемент списка
  185.             free(ptr1); //Освобождение памяти (ptr1)
  186.             free(descriptor->first); //Освобождение памяти (первый элемент)
  187.         }
  188.         else //Если больше двух элементов
  189.         {
  190.             ptr = descriptor->first->next; //Указатель ptr на 2-ой элемент списка
  191.             ptr1 = ptr->next; //Указатель ptr1 на 3-ой элемент списка
  192.             for (i = 2; i < descriptor->N - 1; i++)
  193.             {
  194.                 free(ptr); //Освобождение памяти (ptr)
  195.                 ptr = ptr1; //Указатель ptr на i-ый элемент списка
  196.                 ptr1 = ptr->next; //Указатель ptr1 на i+1-ый элемент списка
  197.             }
  198.             free(ptr); //Освобождение памяти (ptr1)
  199.             free(ptr1); //Освобождение памяти (ptr)
  200.             free(descriptor->first); //Освобождение памяти (первый элемент)
  201.         }
  202.         printf("List is successfully deleted.\n");
  203.         descriptor->list_exists = 0; //Перевод флага в значение "Список отсутствует"
  204.     }
  205. }
  206.  
  207. void ListSearchMax(struct descriptor *descriptor) //Подпрограмма для поиска индексов наибольших элементов списка
  208. {
  209.     int temp, i, oper_count = 0;
  210.     if (descriptor->list_exists == 0) // Если списка не существует
  211.     {
  212.         printf("List wasn't created. Please create it before.\n");
  213.     }
  214.     else //Если список существует
  215.     {
  216.         ptr = descriptor->first;
  217.         oper_count++;
  218.         temp = descriptor->first->data; //Данные первого элемента предполагаем как наибольшие
  219.         for (i = 1; i < descriptor->N; i++) //Цикл поиска наибольшего элемента
  220.         {
  221.             ptr = ptr->next;
  222.             oper_count++;
  223.             if (ptr->data > temp)
  224.             {
  225.                 temp = ptr->data; //Если в i-ом данные >, чем записанные максимальные, то они становятся новыми максимальными
  226.             }
  227.         }
  228.         ptr = descriptor->first;
  229.         oper_count++;
  230.         printf("Max data indexes:\n");
  231.         for (i = 0; i < descriptor->N; i++)
  232.         {
  233.             if (fabs(ptr->data - temp) < 0.00001)
  234.             {
  235.                 printf("[%d]\n", i + 1); //Если 1-ый элемент - наибольший, выводим его индекс
  236.             }
  237.             ptr = ptr->next;
  238.             oper_count++;
  239.         }
  240.         printf("Search for max element is successfully completed.\nElements accessed: %d.\n", oper_count);
  241.     }
  242. }
  243.  
  244. void ListAddData(struct descriptor *descriptor) //Подпрограмма для добавления элемента
  245. {
  246.     int  i, N1, oper_count = 0;
  247.     double temp;
  248.     if (descriptor->list_exists == 0) // Если списка не существует
  249.     {
  250.         printf("List wasn't created. Please create it before.\n");
  251.     }
  252.     else //Если список существeет
  253.     {
  254.         printf("Choose place, where you want to add new data. Avaliable space: from 2 to %d.\n", (descriptor->N) - 1);
  255.         scanf("%d", &N1); //Ввод индекса нового элемента
  256.         if ((N1 > (descriptor->N) - 1) || (N1 < 2)) //Если элемент невозможно добавить
  257.         {
  258.             printf("It's impossible to add new data at that place.");
  259.         }
  260.         else
  261.         {
  262.             ptr1 = malloc(sizeof(struct list)); //Выделение памяти под элемент списка
  263.             ptr = descriptor->first;
  264.             oper_count++;
  265.             for (i = 0; i < N1 - 2; i++)
  266.             {
  267.                 ptr = ptr->next; //Переходим к элементу, предшествующему новому
  268.                 oper_count++;
  269.             }
  270.             ptr1->prev = ptr; //Для нового элемента запись указателя на предыдущий элемент
  271.             ptr = ptr->next; //Переход к элементу, следующему за новым
  272.             oper_count++;
  273.             ptr->prev = ptr1; //Для старого элемента запись указателя на предыдущий элемент (на новый элемент)
  274.             ptr1->next = ptr; //Для нового элемента запись указателя на следующий элемент
  275.             ptr = ptr1->prev; //Возвращение к элементу, предшествующему новому
  276.             oper_count++;
  277.             ptr->next = ptr1; //Для старого элемента запись указателя на следующий элемент (на новый элемент)
  278.             printf("Enter new data.\n"); //Ввод данных в новый элемент
  279.             scanf("%lf", &temp); //Ввод данных в новый элемент
  280.             ptr1->data = temp; //Запись данных в новый элемент списка
  281.             printf("Element is successfully added.\nElements accessed: %d.\n", oper_count);
  282.             (descriptor->N)++;
  283.             ListOutput(descriptor);
  284.         }
  285.     }
  286. }
  287.  
  288. void ListDeleteEnd(struct descriptor *descriptor) //Подпрограмма для удаления последнего элемента списка
  289. {
  290.     int i, oper_count = 0;
  291.     if (descriptor->list_exists == 0) // Если списка не существует
  292.     {
  293.         printf("List wasn't created. Please create it before.\n");
  294.     }
  295.     else //Если список существует
  296.     {
  297.         if (descriptor->N == 1) //Если один элемент
  298.         {
  299.             free(descriptor->first); //Освобождение памяти (дескриптор)
  300.             oper_count++;
  301.             printf("There was only one list element, so the whole list was deleted. Before other operations, please create it.\n");
  302.             descriptor->list_exists = 0;
  303.         }
  304.         else //Если больше одного элемента
  305.         {
  306.             ptr = descriptor->first;
  307.             oper_count++;
  308.             if (descriptor->N > 2) // Если элементов больше 2
  309.             {
  310.                 for (i = 0; i < descriptor->N - 2; i++)
  311.                 {
  312.                     ptr = ptr->next; //Передвигаемся до предпоследнего элемента списка
  313.                     oper_count++;
  314.                 }
  315.             }
  316.             ptr1 = ptr->next; //Указатель ptr1 на предпоследний элемент списка
  317.             oper_count++;
  318.             free(ptr1); //Освобождение памяти (ptr1)
  319.             ptr->next = NULL; //Обнуление указателя на следующий в первом элементе
  320.         }
  321.         printf("The last element is successfully deleted.\nElements accessed: %d.\n", oper_count);
  322.         (descriptor->N)--;
  323.         ListOutput(descriptor);
  324.     }
  325. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement