Удалить из списка все элементы, большие среднего арифметического - C (СИ)

Узнай цену своей работы

Формулировка задачи:

Здравствуйте. Задача такая:Написать программу по созданию, просмотру, добавлению и решению поставленной задачи для двунаправленного линейного списка. Создать список из случайных целых чисел. Удалить из списка все элементы, большие среднего арифметического. Как работать со структурой такого типа я похоже понял, написал алгоритм, функции по созданию, удалению. Теперь суть проблемы: при построении решения ошибок не выдает. В процессе выполнения пункта меню 4 (Удалить из списка все элементы, большие среднего арифметического.) выбрасывает и выдает ошибку: Unhandled exception at 0x01321c54 in Alexey.exe: 0xC0000005: Access violation reading location 0x00000008. Я написал цикл вайлом (те while(t!=NULL)). Как я понимаю как только мой указатель выйдет за список, он укажет в NULL. Соответственно это будет последняя итерация и больше в вайл не войдет. При пошаговой отладке видно, что он проходит 11 раз (я сделал 11 псевдорандомных элементов). Удаляет все элементы, которые больше среднего арифметического и на 11 итерации естественно t уже смотрит в NULL (t=t->Next). Это видно и в окне переменных. Но на 12 итерацию происходит попадание в вайл, уже удалять нечего, т.к. все уже удалено, и по тексту следует t=t->Next;. Которое уже итак смотрит в никуда и тут компилятор выдает ошибку. Надеюсь, моя проблема ясна. Прошу помощи у знающих - что я делаю не так. Так же может быть по остальному тексту что-то режет глаз, тк я новичок. MS VS2010. Код ниже. Спасибо.
Листинг программы
  1. //Написать программу по созданию, просмотру, добавлению и решению поставленной задачи для двунаправленного линейного списка.
  2. //13. Создать список из случайных целых чисел. Удалить из списка все элементы, большие среднего арифметического.
  3. #include<stdio.h>
  4. #include<Windows.h>
  5. #include<conio.h>
  6. #include<math.h>
  7. struct Spis
  8. {
  9. int info;
  10. Spis *Prev,*Next;
  11. };
  12. Spis*begin,*end,*t;
  13. int menu();
  14. void View(Spis*begin); //просмотр списка
  15. Spis* Create(Spis**begin,Spis**end); //создание списка
  16. Spis* Add(Spis**begin,Spis**end); //добавление элемента
  17. void Del(Spis**begin); //удаление списка
  18. void DelMaxMid(Spis*begin); //Удалить из списка все элементы, большие среднего арифметического
  19. void main()
  20. {
  21. SetConsoleCP(1251);
  22. SetConsoleOutputCP(1251);
  23. int menu1;
  24. do
  25. {
  26. menu1=menu();
  27. switch(menu1)
  28. {
  29. case 1: //1 - создать список из случайных целых чисел
  30. {
  31. begin=Create(&begin,&end);
  32. break;
  33. }
  34. case 2: //2 - просмотр списка
  35. {
  36. View(begin);
  37. break;
  38. }
  39. case 3: //3 - добавление элементов списка
  40. {
  41. begin=Add(&begin,&end);
  42. break;
  43. }
  44. case 4: //4 -Удалить из списка все элементы, большие среднего арифметического
  45. {
  46. DelMaxMid(begin);
  47. break;
  48. }
  49. case 5:
  50. {
  51. Del(&begin);
  52. if(begin==NULL)
  53. puts("Проверено! ");
  54. _getch();
  55. }
  56. }
  57.  
  58. }while(menu1!=5);
  59. }
  60. int menu()// меню по созданию, просмотру, добавлению и решению поставленной задачи
  61. {
  62. int enter;
  63. printf("\t\tМЕНЮ ПРОГРАММЫ\n");
  64. printf("\t1 - создать список из случайных целых чисел в диапазоне от 1 до 10\n");
  65. printf("\t2 - просмотр списка\n");
  66. printf("\t3 - добавление элементов списка\n");
  67. printf("\t4 - yдалить из списка все элементы, большие среднего арифметического\n");
  68. printf("\t5 - выход\n");
  69. printf("___________________________________________________________________________\n");
  70. printf("Введите пункт меню: ");
  71. scanf("%d",&enter);
  72. return enter;
  73. }
  74. Spis* Create(Spis**begin,Spis**end)
  75. {
  76. *begin=NULL;
  77. Spis*t=(Spis*)malloc(sizeof(Spis));
  78. t->info=rand()%10;
  79. t->Prev=NULL;
  80. t->Next=NULL;
  81. *begin=*end=t;
  82. for(int i=0;i<10;i++)
  83. {
  84. t=(Spis*)malloc(sizeof(Spis));
  85. t->info=rand()%10;
  86. t->Prev=NULL;
  87. t->Next=*begin;
  88. (*begin)->Prev=t;
  89. *begin=t;
  90. }
  91. printf("\n\tСписок создан\n\n");
  92. return t;
  93. }
  94. void View(Spis*begin)
  95. {
  96. t=begin;
  97. while(t!=NULL)
  98. {
  99. printf("%d\n",t->info);
  100. t=t->Next;
  101. }
  102. }
  103. Spis* Add(Spis**begin,Spis**end)
  104. {
  105. t=(Spis*)malloc(sizeof(Spis));
  106. printf("\n\n Введите значение для добавления: ");
  107. scanf("%d",&t->info);
  108. t->Prev=NULL;
  109. t->Next=*begin;
  110. (*begin)->Prev=t;
  111. *begin=t;
  112. return t;
  113. }
  114. void Del(Spis**begin)
  115. {
  116. Spis*t=*begin;
  117. while(*begin!=NULL)
  118. {
  119. t=*begin;
  120. *begin=(*begin)->Next;
  121. free(t);
  122. }
  123. puts("Память очищена");
  124. }
  125. void DelMaxMid(Spis*begin) //Удалить из списка все элементы, большие среднего арифметического
  126. {
  127. Spis*key=NULL;
  128. int q_namber=0,summ=0; //количество элементов
  129. double s_ar; //среднее арифметическое
  130. t=begin;
  131. while(t!=NULL)
  132. {
  133. q_namber++;
  134. summ+=t->info;
  135. t=t->Next;
  136. }
  137. s_ar=(double)summ/q_namber;
  138. printf("\nСреднее арифметическое: %0.2lf\n",s_ar);
  139. t=begin;
  140. while(t!=NULL)
  141. {
  142. t=begin;
  143. while(t!=NULL) //иду по списку, пока не найду тот эл-т, который больше s_ar; //среднее арифметическое
  144. {
  145. if(t->info>s_ar)
  146. {
  147. key=t;
  148. break;
  149. }
  150. t=t->Next;
  151. }
  152. if(key!=NULL) //cамо удаление из списка
  153. {
  154. if(key==begin) //если элемент расположен в начале
  155. {
  156. begin=begin->Next;
  157. begin->Prev=NULL;
  158. }
  159. else
  160. {
  161. if(key==end) //если он в конце
  162. {
  163. end=end->Prev;
  164. end->Next=NULL;
  165. }
  166. else //или в "теле"
  167. {
  168. (key->Prev)->Next=key->Next;
  169. (key->Next)->Prev=key->Prev;
  170. }
  171. }
  172. free(key); //затираю память
  173. key=NULL;
  174. }
  175. else
  176. t=t->Next;
  177. }
  178. }

Решение задачи: «Удалить из списка все элементы, большие среднего арифметического»

textual
Листинг программы
  1. //Написать программу по созданию, просмотру, добавлению и решению поставленной задачи для двунаправленного линейного списка.
  2. //13. Создать список из случайных целых чисел. Удалить из списка все элементы, большие среднего арифметического.
  3. #include<stdio.h>
  4. #include<Windows.h>
  5. #include<conio.h>
  6. #include<math.h>
  7. struct Spis
  8. {
  9. int info;
  10. Spis *Prev,*Next;
  11. };
  12.  
  13. Spis*begin,*end,*t;
  14. int menu();
  15. void View(Spis*begin);  //просмотр списка
  16. Spis* Create(Spis**begin,Spis**end);    //создание списка
  17. Spis* Add(Spis**begin,Spis**end);   //добавление элемента
  18. void Del(Spis**begin);  //удаление списка
  19. void DelMaxMid(Spis*begin); //Удалить из списка все элементы, большие среднего арифметического
  20. void main()
  21. {
  22. SetConsoleCP(1251);
  23. SetConsoleOutputCP(1251);
  24. int menu1;
  25.  
  26. do
  27. {
  28. menu1=menu();
  29. switch(menu1)
  30. {
  31. case 1: //1 - создать список из случайных целых чисел
  32. {
  33. begin=Create(&begin,&end);
  34. break;
  35. }
  36.  
  37. case 2: //2 - просмотр списка
  38. {
  39. View(begin);
  40. break;
  41. }
  42. case 3: //3 - добавление элементов списка
  43. {
  44. begin=Add(&begin,&end);
  45. break;
  46. }
  47. case 4: //4 -Удалить из списка все элементы, большие среднего арифметического
  48. {
  49. DelMaxMid(begin);
  50. break;
  51. }
  52. case 5:
  53. {
  54. Del(&begin);
  55. if(begin==NULL)
  56. puts("Проверено! ");
  57. _getch();
  58. }
  59.  
  60. }
  61.  
  62.  
  63. }while(menu1!=5);
  64.  
  65. }
  66.  
  67. int menu()// меню по созданию, просмотру, добавлению и решению поставленной задачи
  68. {
  69. int enter;
  70. printf("\t\tМЕНЮ ПРОГРАММЫ\n");
  71. printf("\t1 - создать список из случайных целых чисел в диапазоне от 1 до 10\n");
  72. printf("\t2 - просмотр списка\n");
  73. printf("\t3 - добавление элементов списка\n");
  74. printf("\t4 - yдалить из списка все элементы, большие среднего арифметического\n");
  75. printf("\t5 - выход\n");
  76. printf("<br>\n");
  77. printf("Введите пункт меню: ");
  78. scanf("%d",&enter);
  79. return enter;
  80. }
  81.  
  82. Spis* Create(Spis**begin,Spis**end)
  83. {
  84. *begin=NULL;   
  85. Spis*t=(Spis*)malloc(sizeof(Spis));
  86. t->info=rand()%10;
  87. t->Prev=NULL;
  88. t->Next=NULL;
  89. *begin=*end=t;
  90. for(int i=0;i<10;i++)
  91. {
  92. t=(Spis*)malloc(sizeof(Spis));
  93. t->info=rand()%10;
  94. t->Prev=NULL;
  95. t->Next=*begin;
  96. (*begin)->Prev=t;  
  97. *begin=t;
  98. }
  99. printf("\n\tСписок создан\n\n");
  100. return t;
  101. }
  102.  
  103. void View(Spis*begin)
  104. {
  105. t=begin;
  106. while(t!=NULL)
  107. {
  108. printf("%d\n",t->info);
  109. t=t->Next;
  110. }
  111. }
  112.  
  113. Spis* Add(Spis**begin,Spis**end)
  114. {
  115. t=(Spis*)malloc(sizeof(Spis));
  116. printf("\n\n Введите значение для добавления: ");
  117. scanf("%d",&t->info);
  118. t->Prev=NULL;
  119. t->Next=*begin;
  120. (*begin)->Prev=t;
  121. *begin=t;
  122. return t;
  123. }
  124.  
  125. void Del(Spis**begin)
  126. {
  127. Spis*t=*begin;
  128. while(*begin!=NULL)
  129. {  
  130. t=*begin;
  131. *begin=(*begin)->Next; 
  132. free(t);
  133. }
  134. puts("Память очищена");
  135. }
  136.  
  137. void DelMaxMid(Spis*begin)  //Удалить из списка все элементы, большие среднего арифметического
  138. {
  139. Spis*key=NULL;
  140. int q_namber=0,summ=0;  //количество элементов
  141. double s_ar;    //среднее арифметическое
  142. t=begin;
  143. while(t!=NULL)
  144. {
  145. q_namber++;
  146. summ+=t->info;
  147. t=t->Next;
  148. }
  149. s_ar=(double)summ/q_namber;
  150. printf("\nСреднее арифметическое: %0.2lf\n",s_ar);
  151. t=begin;
  152. while(t!=NULL)
  153. {
  154. t=begin;
  155. while(t!=NULL)  //иду по списку, пока не найду тот эл-т, который больше s_ar;   //среднее арифметическое
  156. {
  157. if(t->info>s_ar)
  158. {
  159. key=t;
  160. break;
  161. }
  162. t=t->Next;
  163. }
  164. if(key!=NULL)   //cамо удаление из списка
  165. {
  166. if(key==begin)  //если элемент расположен в начале
  167. {
  168. begin=begin->Next;
  169. begin->Prev=NULL;
  170. }
  171. else
  172. {
  173. if(key==end)    //если он в конце  
  174. {
  175. end=end->Prev;
  176. end->Next=NULL;
  177. }
  178. else    //или в "теле"
  179. {
  180. (key->Prev)->Next=key->Next;
  181. (key->Next)->Prev=key->Prev;
  182. }
  183. }
  184. free(key);  //затираю память
  185. key=NULL;
  186. }  
  187. else
  188. t=t->Next;
  189. }  
  190. }

Объяснение кода листинга программы

  1. Создание списка из случайных целых чисел в диапазоне от 1 до 10 выполняется в функции Create(Spis**begin,Spis**end).
  2. Просмотр списка осуществляется в функции View(Spis*begin).
  3. Добавление элемента в список выполняется в функции Add(Spis**begin,Spis**end).
  4. Удаление списка выполняется в функции Del(Spis**begin).
  5. Удаление всех элементов списка, больших среднего арифметического, выполняется в функции DelMaxMid(Spis*begin).

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

11   голосов , оценка 4 из 5

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут
Похожие ответы