Удалить из списка все элементы, большие среднего арифметического - 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)
.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д