Задание
На основе прежде разработанного класса управления двонапрямленим списком обеспечить возможность хранения разнотипных данных.
Выбор алгоритма решения задачи
Для решения этой задачи надо использовать базовый класс и 2 класса-потомка в которых все данні сделать закрытыми (для того чтобы при работе случайно не повредить их) и методы обработки этих данных. Уместным я считаю сделать еще один класс с методами: добавление, удаление одного или всех элементов, вывод списка на экран, а также универсальную функцию для добавления и удаление: функция поиска.
Описание алгоритма решения задачи
Основа программы это функция main, поскольку в ней находится меню пользователя из которого можно задействовать любую из функций. Меню всегда находится на экране как в начале работы так и после окончания работы одной из функций, завершение программы происходит при нажатии клавиши Esc.
Удаление всего списка происходит благодаря поочередному переходу с начала до конца списка с одновременным удалением активного элемента.
Добавление/удаление отдельного элемента происходит в два этапа, после того как пользователь выберет место добавления/удаление элемента, функция поиска возвратит показатель на тот элемент который забав пользователь, а потом функция добавления/удаление разорвет цепь и прибавит/удалит элемент.
Функция вывода таблицы поочередно перебирает все элементы списка и выводит список на экран.
Схему алгоритма см. здесь
Функции tabl, find, add и del_all полностью аналогичные функциям с лабораторной работе №7.
Описание программы - см. здесь
Функция tabl: выводит таблицу на экран монитора в которой отображаются все элементы списка.
Текст программы
Head.h
#ifndef _HEAD_H_
#define _HEAD_H_
#include <stdio.h>
#include <iostream>
#include <conio.h>
#include <time.h>
using namespace std;
const int hr=8;
const int NAME=19;
class Base //базовый класс
{
protected: //защищенные данные
char fio[NAME+1];
unsigned int year;
public: //открытые данные
Base *prev, *next; //указатель на следующий и предыдущий
virtual void view(){} //виртуальная функция вывода
};
class Stud : public Base //класс Stud наследник от Base
{
char grup[10]; //поля группа
unsigned int stip; //и стипендия
public:
void add(Stud *p, Base *find); // функция добавления add
void view(); // функция вывода
};
class Prep : public Base //класс Prep наследник от Base
{
unsigned int stag, zarp; //поля stag и zarp
public:
void add(Prep *p, Base *find); // функция добавления add
void view(); // функция вывода
};
class mtd // класс mtd, который не имеет наследования
{
public: //открытые функции
Base *Find(int n); //поиск
void tabl(); //вывод таблицы
void del(Base *find); //удаление
void del_all(); //удалить все
};
#endif
6.2 Func.cpp
#include "Head.h" //подключение файла Head.h
int KEY, COUNT;
Base *FIRST;
Base * mtd::Find(int n) //реализация функции mtd для поиска
{ //нужного места в списке
Base *temp;
temp=FIRST;
int i=0;
Base *p;
if (n>0)
{
if (temp==NULL) //если список еще не создан
{
KEY=1;
return temp;
}
else
{
if (n==1) //если введена первая позиция
{
KEY=1;
return temp;
}
else //иначе введено число больше чем 1
{
while (i<n-1) //пока не достигнут конец списка
{
p=temp;
if (p->next==NULL) //если уже конец списка
{
i=n;
KEY=0;
return p; //возврат указателя на посдедний элемент списка
}
else //если не конец списка
{
temp=p->next;
i++;
}
}
KEY=1;
return temp;
}
}
}
else //иначе введено n<1 список не может быть создан
{
KEY=-1;
cout<<"Zadanoe chislo ne vhodit v predel spiska...\a\n";
}
return FIRST;
}
////////////////////////////////////////////////////////////////////////
void Stud::add(Stud *p, Base *find) //функция добавления в класе Stud
{
if (KEY>=0) // если key>=0 тогда можна добавить список
{
if (find==NULL) //если списка еще нет
{
p->prev=NULL;
FIRST=p;
p->next=NULL;
}
else
{
if (KEY==0) //если список достигнут конца
{
p->prev=find;
p->next=NULL;
find->next=p;
}
else //иначе позиция не достигла конца
{
if (find==FIRST!=NULL) //если fin==first!=0 то это первый список
{
p->prev=NULL;
p->next=FIRST;
find->prev=p;
FIRST=p;
}
else
{
if (find!=FIRST) //это не первый список. Добавлять нужно в середине
{ //списка
p->prev=find->prev;
p->next=find;
p->prev->next=p;
find->prev=p;
}
}
}
}
}
srand(unsigned(time(NULL)));
int y,s,flag=0,key=0;
char ch;
cout<<"1. Vvesti FIO\n";
cout<<"2. Sgenerirovat' FIO\n\n";
while (!key)
{
key=0;
ch=getch();
switch(ch) //выбор ввода данных: вручную или сгенерировать
{
case '1':
cout<<"Vvedite FIO ";
cin>>fio;
cout<<endl;
key=1;
break;
case '2':
for (s=0;s<NAME;s++)
fio[s]=char((rand()%26)+64);
fio[s]='\0';
key=1;
break;
}
}
year=(rand()%10)+1980;
for (s=0;s<10;s++)
grup[s]=char((rand()%26)+64);
grup[s]='\0';
stip=(rand()%300)+500;
}
////////////////////////////////////////////////////////////////////////
void Prep::add(Prep *p, Base *find) //функция добавления в класе Prep
{ // аналогичная функция добавления в класе Stud
if (KEY>=0)
{
if (find==NULL)
{
p->prev=NULL;
FIRST=p;
p->next=NULL;
}
else
{
if (KEY==0)
{
p->prev=find;
p->next=NULL;
find->next=p;
}
else
{
if (find==FIRST!=NULL)
{
p->prev=NULL;
p->next=FIRST;
find->prev=p;
FIRST=p;
}
else
{
if (find!=FIRST)
{
p->prev=find->prev;
p->next=find;
p->prev->next=p;
find->prev=p;
}
}
}
}
}
srand(unsigned(time(NULL)));
int y,s,flag=0,key=0;
char ch;
cout<<"1. Vvesti FIO\n";
cout<<"2. Sgenerirovat' FIO\n\n";
while (!key)
{
key=0;
ch=getch();
switch(ch)
{
case '1':
cout<<"Vvedite FIO ";
cin>>fio;
cout<<endl;
key=1;
break;
case '2':
for (s=0;s<NAME;s++)
fio[s]=char((rand()%26)+64);
fio[s]='\0';
key=1;
break;
}
}
year=(rand()%45)+1940;
stag=2009-year-25;
zarp=(rand()%300)+500;
}
////////////////////////////////////////////////////////////////////////
void mtd::tabl() // вывод таблицы на экран
{
Base *temp;
temp=FIRST;
int key=1,x=0;
if (FIRST!=NULL)
{
printf(" -------------------------------------------------------------\n");
printf("| | | | | | | |\n");
printf("| No | FIO | Year | Stag | Gryppa | Zarplata | Stipendia |\n");
printf("|-----|-------|------|------|----------|----------|-----------|\n");
while (key)
{
++x;
printf("|%5d|",x);
temp->view();
cout<<endl;
if (temp->next==NULL)
key=0;
else
temp=temp->next;
}
printf(" ----------------------------------------------------------\n\n");
}
else
cout<<"\nNe zadano kolichestvo rabochih\n";
}
////////////////////////////////////////////////////////////////////////
void Stud::view() //функция выводу информации о студентах
{
printf("%20s|%6d| |%10s| |%11d|",fio,year,grup,stip);
}
////////////////////////////////////////////////////////////////////////
void Prep::view() //функция выводу информации о преподавателях
{
printf("%20s|%6d|%6d| |%10d| |",fio,year,stag,zarp);
}
////////////////////////////////////////////////////////////////////////
void mtd::del_all() //функция удалить все
{
Base *p;
int flag=1;
if (FIRST!=NULL)
{
if (flag!=0)
{
p=FIRST;
if (p->next==0)
flag=0;
else
FIRST=p->next;
delete p;
}
}
FIRST=NULL;
}
////////////////////////////////////////////////////////////////////////
void mtd::del(Base *find) //функция удались 1 элемент списка
{
Base *p, *temp;
if (KEY>=0)
{
if (find==0) //если список пуст, то нечего удалять
{
cout<<"Spisok pyst!\n";
getch();
}
else
{
if (KEY==0) //если в списке нет такого элемента
{
cout<<"Takogo elementa nety v spiske!";
getch();
}
else
{
if (find==FIRST!=0) //если это первый элемент
{
if (FIRST->next==0) //и если он последний
{
p=FIRST;
delete p;
FIRST=0;
}
else //иначе он не последний
{
p=FIRST;
FIRST=p->next;
FIRST->prev=0;
delete p;
}
}
else //если это не первый элемент
{
if (find!=FIRST)
{
p=find;
if (p->next==0) //если он последний
{
p->prev->next=0;
delete p;
}
else //иначе он не последний
{
find->prev->next=p->next;
p->next->prev=find->prev;
delete p;
}
}
}
}
}
}
}
6.3 Main.cpp
#include "Head.h"
extern Base *FIRST;
mtd *fun;
void main(void)
{
mtd *p;
p=new mtd;
int end=0;
char ch;
while(!end) //пока не нажата клавиша ESC
{
system("cls");
cout<<"1. Dobavit' v spisok\n";
cout<<"2. Pokazat' spisok\n";
cout<<"3. Ydalit' element\n";
cout<<"4. Ydalit' spisok\n";
cout<<"Esc. Exit\n";
ch=getch();
switch (ch) // оператор выбора
{
case '1':
system("cls");
cout<<"1. Stydent\n";
cout<<"2. Prepodavatel'\n";
int n;
char chr;
chr=getch();
switch (chr)
{
case '1':
cout<<"\nVvedite piziciy - ";
cin>>n;
Stud *s;
s=new Stud;
s->add(s, p->Find(n));
break;
case '2':
cout<<"\nVvedite piziciy - ";
cin>>n;
Prep *pr;
pr=new Prep;
pr->add(pr, p->Find(n));
break;
}
break;
case '2':
system("cls");
if (FIRST)
p->tabl();
else
cout<<"Spisok pyst...\n";
getch();
break;
case '3':
system("cls");
if (FIRST)
{
cout<<"\nVvedite nomer elementa - ";
cin>>n;
p->del(p->Find(n));
}
else
{
cout<<"Spisok pyst...\n";
getch();
}
break;
case '4':
system("cls");
if (FIRST)
p->del_all();
else
{
cout<<"Spisok pyst...\n";
getch();
}
break;
case 27: //выход из программы
end=1;
break;
}
}
p->del_all(); //освобождение динамической памяти
delete p;
}
Результат работы программы