Удалить из списка все элементы, большие среднего арифметического - 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. Создание списка из случайных целых чисел в диапазоне от 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
Похожие ответы