Удалить из списка все элементы, большие среднего арифметического - 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. Код ниже. Спасибо.
Листинг программы
- //Написать программу по созданию, просмотру, добавлению и решению поставленной задачи для двунаправленного линейного списка.
- //13. Создать список из случайных целых чисел. Удалить из списка все элементы, большие среднего арифметического.
- #include<stdio.h>
- #include<Windows.h>
- #include<conio.h>
- #include<math.h>
- struct Spis
- {
- int info;
- Spis *Prev,*Next;
- };
- Spis*begin,*end,*t;
- int menu();
- void View(Spis*begin); //просмотр списка
- Spis* Create(Spis**begin,Spis**end); //создание списка
- Spis* Add(Spis**begin,Spis**end); //добавление элемента
- void Del(Spis**begin); //удаление списка
- void DelMaxMid(Spis*begin); //Удалить из списка все элементы, большие среднего арифметического
- void main()
- {
- SetConsoleCP(1251);
- SetConsoleOutputCP(1251);
- int menu1;
- do
- {
- menu1=menu();
- switch(menu1)
- {
- case 1: //1 - создать список из случайных целых чисел
- {
- begin=Create(&begin,&end);
- break;
- }
- case 2: //2 - просмотр списка
- {
- View(begin);
- break;
- }
- case 3: //3 - добавление элементов списка
- {
- begin=Add(&begin,&end);
- break;
- }
- case 4: //4 -Удалить из списка все элементы, большие среднего арифметического
- {
- DelMaxMid(begin);
- break;
- }
- case 5:
- {
- Del(&begin);
- if(begin==NULL)
- puts("Проверено! ");
- _getch();
- }
- }
- }while(menu1!=5);
- }
- int menu()// меню по созданию, просмотру, добавлению и решению поставленной задачи
- {
- int enter;
- printf("\t\tМЕНЮ ПРОГРАММЫ\n");
- printf("\t1 - создать список из случайных целых чисел в диапазоне от 1 до 10\n");
- printf("\t2 - просмотр списка\n");
- printf("\t3 - добавление элементов списка\n");
- printf("\t4 - yдалить из списка все элементы, большие среднего арифметического\n");
- printf("\t5 - выход\n");
- printf("___________________________________________________________________________\n");
- printf("Введите пункт меню: ");
- scanf("%d",&enter);
- return enter;
- }
- Spis* Create(Spis**begin,Spis**end)
- {
- *begin=NULL;
- Spis*t=(Spis*)malloc(sizeof(Spis));
- t->info=rand()%10;
- t->Prev=NULL;
- t->Next=NULL;
- *begin=*end=t;
- for(int i=0;i<10;i++)
- {
- t=(Spis*)malloc(sizeof(Spis));
- t->info=rand()%10;
- t->Prev=NULL;
- t->Next=*begin;
- (*begin)->Prev=t;
- *begin=t;
- }
- printf("\n\tСписок создан\n\n");
- return t;
- }
- void View(Spis*begin)
- {
- t=begin;
- while(t!=NULL)
- {
- printf("%d\n",t->info);
- t=t->Next;
- }
- }
- Spis* Add(Spis**begin,Spis**end)
- {
- t=(Spis*)malloc(sizeof(Spis));
- printf("\n\n Введите значение для добавления: ");
- scanf("%d",&t->info);
- t->Prev=NULL;
- t->Next=*begin;
- (*begin)->Prev=t;
- *begin=t;
- return t;
- }
- void Del(Spis**begin)
- {
- Spis*t=*begin;
- while(*begin!=NULL)
- {
- t=*begin;
- *begin=(*begin)->Next;
- free(t);
- }
- puts("Память очищена");
- }
- void DelMaxMid(Spis*begin) //Удалить из списка все элементы, большие среднего арифметического
- {
- Spis*key=NULL;
- int q_namber=0,summ=0; //количество элементов
- double s_ar; //среднее арифметическое
- t=begin;
- while(t!=NULL)
- {
- q_namber++;
- summ+=t->info;
- t=t->Next;
- }
- s_ar=(double)summ/q_namber;
- printf("\nСреднее арифметическое: %0.2lf\n",s_ar);
- t=begin;
- while(t!=NULL)
- {
- t=begin;
- while(t!=NULL) //иду по списку, пока не найду тот эл-т, который больше s_ar; //среднее арифметическое
- {
- if(t->info>s_ar)
- {
- key=t;
- break;
- }
- t=t->Next;
- }
- if(key!=NULL) //cамо удаление из списка
- {
- if(key==begin) //если элемент расположен в начале
- {
- begin=begin->Next;
- begin->Prev=NULL;
- }
- else
- {
- if(key==end) //если он в конце
- {
- end=end->Prev;
- end->Next=NULL;
- }
- else //или в "теле"
- {
- (key->Prev)->Next=key->Next;
- (key->Next)->Prev=key->Prev;
- }
- }
- free(key); //затираю память
- key=NULL;
- }
- else
- t=t->Next;
- }
- }
Решение задачи: «Удалить из списка все элементы, большие среднего арифметического»
textual
Листинг программы
- //Написать программу по созданию, просмотру, добавлению и решению поставленной задачи для двунаправленного линейного списка.
- //13. Создать список из случайных целых чисел. Удалить из списка все элементы, большие среднего арифметического.
- #include<stdio.h>
- #include<Windows.h>
- #include<conio.h>
- #include<math.h>
- struct Spis
- {
- int info;
- Spis *Prev,*Next;
- };
- Spis*begin,*end,*t;
- int menu();
- void View(Spis*begin); //просмотр списка
- Spis* Create(Spis**begin,Spis**end); //создание списка
- Spis* Add(Spis**begin,Spis**end); //добавление элемента
- void Del(Spis**begin); //удаление списка
- void DelMaxMid(Spis*begin); //Удалить из списка все элементы, большие среднего арифметического
- void main()
- {
- SetConsoleCP(1251);
- SetConsoleOutputCP(1251);
- int menu1;
- do
- {
- menu1=menu();
- switch(menu1)
- {
- case 1: //1 - создать список из случайных целых чисел
- {
- begin=Create(&begin,&end);
- break;
- }
- case 2: //2 - просмотр списка
- {
- View(begin);
- break;
- }
- case 3: //3 - добавление элементов списка
- {
- begin=Add(&begin,&end);
- break;
- }
- case 4: //4 -Удалить из списка все элементы, большие среднего арифметического
- {
- DelMaxMid(begin);
- break;
- }
- case 5:
- {
- Del(&begin);
- if(begin==NULL)
- puts("Проверено! ");
- _getch();
- }
- }
- }while(menu1!=5);
- }
- int menu()// меню по созданию, просмотру, добавлению и решению поставленной задачи
- {
- int enter;
- printf("\t\tМЕНЮ ПРОГРАММЫ\n");
- printf("\t1 - создать список из случайных целых чисел в диапазоне от 1 до 10\n");
- printf("\t2 - просмотр списка\n");
- printf("\t3 - добавление элементов списка\n");
- printf("\t4 - yдалить из списка все элементы, большие среднего арифметического\n");
- printf("\t5 - выход\n");
- printf("<br>\n");
- printf("Введите пункт меню: ");
- scanf("%d",&enter);
- return enter;
- }
- Spis* Create(Spis**begin,Spis**end)
- {
- *begin=NULL;
- Spis*t=(Spis*)malloc(sizeof(Spis));
- t->info=rand()%10;
- t->Prev=NULL;
- t->Next=NULL;
- *begin=*end=t;
- for(int i=0;i<10;i++)
- {
- t=(Spis*)malloc(sizeof(Spis));
- t->info=rand()%10;
- t->Prev=NULL;
- t->Next=*begin;
- (*begin)->Prev=t;
- *begin=t;
- }
- printf("\n\tСписок создан\n\n");
- return t;
- }
- void View(Spis*begin)
- {
- t=begin;
- while(t!=NULL)
- {
- printf("%d\n",t->info);
- t=t->Next;
- }
- }
- Spis* Add(Spis**begin,Spis**end)
- {
- t=(Spis*)malloc(sizeof(Spis));
- printf("\n\n Введите значение для добавления: ");
- scanf("%d",&t->info);
- t->Prev=NULL;
- t->Next=*begin;
- (*begin)->Prev=t;
- *begin=t;
- return t;
- }
- void Del(Spis**begin)
- {
- Spis*t=*begin;
- while(*begin!=NULL)
- {
- t=*begin;
- *begin=(*begin)->Next;
- free(t);
- }
- puts("Память очищена");
- }
- void DelMaxMid(Spis*begin) //Удалить из списка все элементы, большие среднего арифметического
- {
- Spis*key=NULL;
- int q_namber=0,summ=0; //количество элементов
- double s_ar; //среднее арифметическое
- t=begin;
- while(t!=NULL)
- {
- q_namber++;
- summ+=t->info;
- t=t->Next;
- }
- s_ar=(double)summ/q_namber;
- printf("\nСреднее арифметическое: %0.2lf\n",s_ar);
- t=begin;
- while(t!=NULL)
- {
- t=begin;
- while(t!=NULL) //иду по списку, пока не найду тот эл-т, который больше s_ar; //среднее арифметическое
- {
- if(t->info>s_ar)
- {
- key=t;
- break;
- }
- t=t->Next;
- }
- if(key!=NULL) //cамо удаление из списка
- {
- if(key==begin) //если элемент расположен в начале
- {
- begin=begin->Next;
- begin->Prev=NULL;
- }
- else
- {
- if(key==end) //если он в конце
- {
- end=end->Prev;
- end->Next=NULL;
- }
- else //или в "теле"
- {
- (key->Prev)->Next=key->Next;
- (key->Next)->Prev=key->Prev;
- }
- }
- free(key); //затираю память
- key=NULL;
- }
- else
- t=t->Next;
- }
- }
Объяснение кода листинга программы
- Создание списка из случайных целых чисел в диапазоне от 1 до 10 выполняется в функции
Create(Spis**begin,Spis**end)
. - Просмотр списка осуществляется в функции
View(Spis*begin)
. - Добавление элемента в список выполняется в функции
Add(Spis**begin,Spis**end)
. - Удаление списка выполняется в функции
Del(Spis**begin)
. - Удаление всех элементов списка, больших среднего арифметического, выполняется в функции
DelMaxMid(Spis*begin)
.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д