двусвязный список из структур
1. Создание списка.
2. Просмотр списка.
3. Добавление в конец списка новой структуры.
4. Корректировка списка.
5. Выход.
Структура содержит название книги, автора, год издания. п4.- Удалить издания с годом меньше заданного.
#include <stdio.h>
#include <conio.h>
#include <malloc.h>
#include <io.h>
//=============================//////===============================
struct Book
{
char nazv[10];
char avtor[20];
int godizd;
Book* next;
Book* prev;
};
struct list
{
Book* first;
Book* last;
};
void menu();
void addBook(list&);
void delBook(list&);
void printlist(list*);
void createlist(list*&);
list* thelist=0;
int main()
{
list* first=0;
list* last=0;
menu();
getche();
return 0;
}
void menu()
{char quit;
enum{false,true};
quit = false;
while(true)
{
int choice;
printf("\n -----MENU-----\n");
printf("(1) vvedite spisok \n");
printf("(2) prosmotr \n");
printf("(3) dobavlenie \n");
printf("(4) ydalenie \n");
printf("(5) exit \n");
scanf("%d", &choice);
switch (choice)
{
case(1): if (!thelist)
{
createlist(thelist );
printf(" the list has been created succesfully... \n");
}
else
printf(" the list is already created...\n" );
break;
case(2):
if (thelist)
printlist(thelist);
else
printf(" the list is not created...\n");
break;
case(3):
if (thelist)
addBook(*thelist);
else
printf(" the list is not created...\n");
break;
case 4:
if (thelist)
delBook(*thelist);
else
printf(" the list is not created... \n");
break;
case(5):
quit = true;
}
if (quit == true)
break;
}
}
//==============================/////////===================================
void addBook(list& thelist)
{
printf("\n *** dobavit' novuy knigy *** \n");
printf(" vvedite nazvanie: ");
Book* newBook = new Book;
scanf("%s",&newBook->nazv);
printf(" vvedite avtora: ");
scanf("%s",&newBook->avtor);
printf(" vvedite god izdania: ");
scanf("%d",&newBook->godizd);
if (thelist.last)
{
thelist.last->next = newBook;
newBook->prev = thelist.last;
}
else
{
thelist.first = newBook;
newBook->prev = 0;
}
thelist.last = newBook;
newBook->next = 0;
printf("*** book was added successfully *** \n");
}
//=======================================///////////////==========================
void createlist (list*& thelist)
{
thelist = new list;
thelist->first = NULL;
thelist->last = NULL;
Book *p,*k=NULL;
do
{
p = new Book;
printf( "*** vvedite knigy *** \n");
printf(" vvedite nazv: ");
scanf("%s", &p->nazv);
printf( " vvedite avtora: " );
scanf("%s", &p->avtor);
printf(" vvedite god izdania: ");
scanf( "%d",&p->godizd);
if(thelist->first==NULL) thelist->first = p;
p->next = NULL;
if(k)
{
p->prev = k;
k->next = p;
}
else
{
p->prev = NULL;
}
k = p;
puts(" Zakonchit' - <esc>");
}
while (getch()!=27);
thelist->last=p;
}
//=======================================================///////////============================
void printlist(list* thelist)
{
printf("\n *** prosmotr knig *** \n");
Book* curBook = thelist->first;
while (curBook)
{
// printf("%s\n",curBook->nazv);
// printf("%s\n",&curBook->avtor);
// printf("%d\n",&curBook->godizd);
// curBook = curBook->next;
printf("\n %s %s %d ",curBook->nazv,curBook->avtor,curBook->godizd);
curBook = curBook->next;
}
printf("\n *** end *** \n" );
}
//=================//======================//=======================//
void delBook(list& thelist)
{
Book* curBook = thelist.first;
int Pos;
printf( " Enter the godizdania for deleted Book: \n");
scanf("%d",&Pos);
printf("%d",Pos);
for (int i=0; i<Pos ; i++)
{
if (curBook)
curBook = curBook->next;
}
if (curBook && (Pos >= 0))
{
if (curBook->prev)
{
curBook->prev->next = curBook->next;
}
else
{
thelist.first = curBook->next;
}
if (curBook->next)
{
curBook->next->prev = curBook->prev;
}
else
{
thelist.last = curBook->prev;
}
delete curBook;
printf("Book ? ", Pos ," has been deleted successfully..." );
}
else
printf("Book ? ", Pos , " not found..." );
}
Тут куча ошибок , помогите исправить.
Ты определись, ты передаешь указатель, или ссылку на объект.
Что это?
Дальше смотреть не стал.
{
Book* first;
Book* last;
};
list* last=0;
Ммм... зачем?
Получается first->first; first->last; бред какой то.
Тебе нужен указетель Book* first; его ты будешь передавать в функции добавления, вывода, удаления.
И зачем здесь двухсвязанный, если можно обойтись односвязанным списком?
В функции удаления что т много всего.
Вводишь год издания, открываешь цикл while до конца списка, в котором сравниваешь год издания текущей книги с годом издания, который ввел. Если меньше, то перенаправляешь указатели и высвобождаешь память из под элемента.
//если такого значения инф поля нет то список оставлять таким?
var
p,q,t:PList;
begin
p:=first;
t:=GetByValue(x);
if t=nil then writeln('element not find')
else
begin
while (p<>nil) do
begin
if p^.inf > x then
begin //нашли нужные значения
if p = first then
begin //если удаляем первый элемент
first := p^.next; //то редактируем указатель начала
first^.prior := nil;
//удалить
end
else
if p^.next = nil then p^.prior^.next := nil
else//если последний, то редактируем предпоследний
begin //если где-то в середине
p^.prior^.next := p^.next;//редактируем
p^.next^.prior := p^.prior;//соседнии элементы
end;
q := p; //указатель на удаляемый элемент
p := p^.next;
dispose(q);//удаляем
continue
end;
p:=p^.next;
end;
end;
end;
Вот нашел похожее, что то похожее то ли на Паскале. то ли на Делфи. Не поможешь в си перевести.
Я нет.
Набросал на коленке примерный код для удаления, на правильность не претендую :)
Book* temp;
int year;
cur = first;
printf( " Enter the godizdania for deleted Book: \n");
scanf("%d",&year);
while (cur != NULL) {
if(cur->godizd < year) {
if (cur->prev == NULL) { //если удаляем первый элемент
first = cur->next; //первым будет второй элемент в списке
first->prev = NULL;
free(cur); //высвободили память
cur = first; //перевели указатель на второй элемент
}else {//если элемент не первый
temp = cur;
cur->prev->next = cur->next; //с предыдущего элемета указали на последующий
cur->next->prev = cur->prev; //со следующего элнемента указали на предыдущий
cur= cur->prev; //текущий будет тот, который стоит перед удаляемым
free(temp);
}
} else cur = cur->next;
}
int year; переменная не связана с общей структурой или я чего то не пойму?
про first я тебе говорил выше
В year я ввожу год, меньше которого нужно удалить, смотри ниже
clrscr();
head2();
textcolor(4);
cprintf(" Меню:");
cout<<"\n";
textcolor(14);
cprintf("1)Удалить запись по номеру в таблице");
cout<<"\n";
cprintf("2)Удалить все");
cout<<"\n";
cprintf("3)Назад");
cout<<"\n";
textcolor(4);
cout<<"\n\n";
cprintf("Выберите любое действие...");
textcolor(7);
DT *l;// указатель на структуру
l=k=first;// доп переменные для удаления используются
switch(getch())
{
case 49:
clrscr();
head2();
textcolor(14);
cprintf("Введите номер записи, которую хотите удалить: ");
textcolor(7);
cin>>t;
fl=0;
int temp=pluser(first);
strcpy(s,"y");
do
{
if(t>temp)
{
clrscr();
head2();
textcolor(4);
cprintf("Такой записи не существует! Попробовать снова?");
textcolor(14);
cprintf("(y/n): ");
cin>>s;
textcolor(7);
if(strcmp(s,"y")==0)
{
clrscr();
head2();
textcolor(14);
cprintf("Введите номер записи, которую хотите удалить: ");
textcolor(7);
cin>>t;
}
else
if(strcmp(s,"n")==0)break;
else
{
cout<<"\n";
textcolor(14);
cprintf("Ошибка в выборе действия, повторите попытку!");
cout<<"\n\n\n";
textcolor(4);
cprintf("Нажмити любую клавишу для продолжения...");
textcolor(7);
getch();
clrscr();
}
}
}
while(t>temp);
if(strcmp(s,"y")==0)
{
if(t==k->numer)
{
fl=1;
[COLOR="Red"]if(k->next==NULL)//если одна запись удаляем
{
delete k;
delete first;
delete last;
first=last=NULL;
}
}
while(k!=NULL)// если есть больше 1 записи
{
fl=1;
if(t==k->numer)
{
if(k==first)//если 1-ая запись удаляем
{
q=k;
first=k->next;
first->prev=NULL;
l=k=first;
delete q;
}
else if(k==last)// если последняя запись удаляем
{
q=k;
last=k->prev;
last->next=NULL;
k=NULL;
delete q;
}
else// если запись в середине удаляем
{
q=k;
l->next=k->next;
k->next->prev=l;
delete q;
k=l->next;
}
}
else// если нет такой записи, просматриваем слудющую
{
l=k;
k=k->next;
}
}[/COLOR]
if(fl==1)
{
cout<<"\n\n";
textcolor(2);
cprintf("Запись успешно удалена!");
cout<<"\n\n";
textcolor(4);
cprintf("Нажмити любую клавишу для продолжения...");
textcolor(7);
getch();
}
}
break;
case 50:
clrscr();
[COLOR="Red"]k=first;
while(k!=NULL)// удаляем весь список сразу
{
first=k->next;
delete k;
k=first;
}
first=last=NULL;[/COLOR]
textcolor(2);
cprintf("База успешно очищена!");
cout<<"\n\n";
textcolor(4);
cprintf("Нажмити любую клавишу для продолжения...");
textcolor(7);
getch();
break;
Короче этот кусок кода должен помочь тебе, он вырезан из работы, так что адаптируй под свой код самостоятельно все работает праверено:)
class turn // который удовлетворяет правилу FIFO
{
public:
int v; // значение номера вершины
turn *next; // указатель на следующий элемент списка
turn *pred; // указатель на предыдущий элемент списка
};
turn *newTurnEl(int v,turn *next = NULL, turn *pred = NULL)
{ // функция создания нового объекта класса turn
turn *nTrn = new turn;
nTrn->v = v;
nTrn->next = next;
nTrn->pred = pred;
return nTrn;
}
void InitTurn(turn *begin,turn *end) // функция инициализации списка
{
begin->next = end;
end->pred = begin;
begin->pred = NULL;
end->next = NULL;
}
void addElTurn(turn *begin,turn *end,turn *nTrn) // функция добавления
{ // объекта в список
begin->next->pred = nTrn;
nTrn->pred = begin;
nTrn->next = begin->next;
begin->next = nTrn;
}
void delElTurn(turn *begin,turn *end) // функция удаления объекта из списка
{
if (end->pred!=begin)
{
turn *oTrn = end->pred;
end->pred = oTrn->pred;
oTrn->pred->next = end;
delete oTrn;
}
}
// функция удаления списка со всеми элементами
void delTurn(turn *begin,turn *end)
{
while (end->pred!=begin) delElTurn(begin,end);
delete begin;
delete end;
}
сменить class на struct и добавить нужных полей и функций... проблем не должно составить
п.с. инглишь тогда знал вообще отвратно, поэтому вусвязный список turn окрестил:D
#include <stdio.h>
#include <conio.h>
#include <malloc.h>
#include <io.h>
//=============================//////===============================
struct Book
{
char nazv[10];
char avtor[20];
int godizd;
Book* next;
Book* prev;
};
struct list
{
Book* first;
Book* last;
};
void menu();
void addBook(list&);
void delBook(list&);
void printlist(list*);
void createlist(list*&);
list* thelist=0;
int main()
{
menu();
getch();
return 0;
}
void menu()
{ char quit;
enum{false,true};
quit = false;
while(true)
{
int choice;
printf("\n -----MENU-----\n");
printf("(1) vvedite spisok \n");
printf("(2) prosmotr \n");
printf("(3) dobavlenie \n");
printf("(4) ydalenie \n");
printf("(5) exit \n");
scanf("%d", &choice);
switch (choice)
{
case(1): if (!thelist)
{
createlist(thelist );
printf(" the list has been created succesfully... \n");
}
else
printf(" the list is already created...\n" );
break;
case(2):
if (thelist)
printlist(thelist);
else
printf(" the list is not created...\n");
break;
case(3):
if (thelist)
addBook(*thelist);
else
printf(" the list is not created...\n");
break;
case 4:
if (thelist)
delBook(*thelist);
else
printf(" the list is not created... \n");
break;
case(5):
quit = true;
}
if (quit == true)
break;
}
}
//==============================/////////===================================
void addBook(list& thelist)
{
printf("\n *** dobavit' novuy knigy *** \n");
printf(" vvedite nazvanie: ");
Book* newBook = new Book;
scanf("%s",&newBook->nazv);
printf(" vvedite avtora: ");
scanf("%s",&newBook->avtor);
printf(" vvedite god izdania: ");
scanf("%d",&newBook->godizd);
if (thelist.last)
{
thelist.last->next = newBook;
newBook->prev = thelist.last;
}
else
{
thelist.first = newBook;
newBook->prev = 0;
}
thelist.last = newBook;
newBook->next = 0;
printf("*** book was added successfully *** \n");
}
//=======================================///////////////==========================
void createlist (list*& thelist)
{
thelist = new list;
thelist->first = NULL;
thelist->last = NULL;
Book *p,*k=NULL;
do
{
p = new Book;
printf( "*** vvedite knigy *** \n");
printf(" vvedite nazv: ");
scanf("%s", &p->nazv);
printf( " vvedite avtora: " );
scanf("%s", &p->avtor);
printf(" vvedite god izdania: ");
scanf( "%d",&p->godizd);
if(thelist->first==NULL) thelist->first = p;
p->next = NULL;
if(k)
{
p->prev = k;
k->next = p;
}
else
{
p->prev = NULL;
}
k = p;
puts(" Zakonchit' - <esc>");
}
while (getch()!=27);
thelist->last=p;
}
//=======================================================///////////============================
void printlist(list* thelist)
{
printf("\n *** prosmotr knig *** \n");
Book* curBook = thelist->first;
while (curBook)
{
// printf("%s\n",curBook->nazv);
// printf("%s\n",&curBook->avtor);
// printf("%d\n",&curBook->godizd);
// curBook = curBook->next;
printf("\n %s %s %d ",curBook->nazv,curBook->avtor,curBook->godizd);
curBook = curBook->next;
}
printf("\n *** end *** \n" );
}
//=================//======================//=======================//
void delBook(list& thelist)
{Book* cur=thelist.first;
Book* temp;
int year;
cur =thelist. first;
printf( " Enter the godizdania for deleted Book: \n");
scanf("%d",&year);
while (cur != NULL) {
if(cur->godizd < year) {
if (cur->prev == NULL) { //если удаляем первый элемент
thelist.first = cur->next; //первым будет второй элемент в списке
thelist.first->prev = NULL;
free(cur); //высвободили память
cur = thelist.first; //перевели указатель на второй элемент
}else {//если элемент не первый
temp = cur;
cur->prev->next = cur->next; //с предыдущего элемета указали на последующий
cur->next->prev = cur->prev; //со следующего элнемента указали на предыдущий
cur= cur->prev; //текущий будет тот, который стоит перед удаляемым
free(temp);
}
} else cur = cur->next;
}
}
Вот так вроде все работает, скомпилируйте кто-нить посмотрите, может что то изменить можно или упростить.Мне просто курсовой по этой проге писать, а я новичок без опыта поэтому к каждому совету и замечанию отношусь серьезно. Хочется чтобы все работало как часы.