struct node
{
node* prev;
node* next;
int useful;
};
динамические структуры
1) Кольцевой двунаправленный список (добавление/удаление в произвольное место списка, отличное от начала (например после звена, указатель на которое задан). Проверка, пуст ли список, очистка списка, печать списка в направлении от верха к низу \ низа к верху.
Необходимо написать программу на С++.
Спасибо всем, заранее!
Цитата: life4fun
Доброго вечера. Пожалуйста помогите разобраться с заданием на структуры, и подскажите с чего здесь начинать?
1) Кольцевой двунаправленный список (добавление/удаление в произвольное место списка, отличное от начала (например после звена, указатель на которое задан). Проверка, пуст ли список, очистка списка, печать списка в направлении от верха к низу \ низа к верху.
Необходимо написать программу на С++.
Спасибо всем, заранее!
1) Кольцевой двунаправленный список (добавление/удаление в произвольное место списка, отличное от начала (например после звена, указатель на которое задан). Проверка, пуст ли список, очистка списка, печать списка в направлении от верха к низу \ низа к верху.
Необходимо написать программу на С++.
Спасибо всем, заранее!
Что конкретно непонятно? Наброски кода, где? Если всего этого нету, то дорога тебе во фриланс.
Таки покажите что вы что-то делали. Поиск по форуму попробуйте. Лично я один раз точно выкладывал код двунаправленного списка (правда там скорее си-стиль, но написано было на С++).
чего здесь начинать?
Начни с описания нода для списка. Его структура данных может быть такой:
Код:
Проверка, пуст ли список, очистка списка, печать списка в направлении от верха к низу \ низа к верху.
Дональд Кнут "Искусство программирования"
Код:
struct Node{
//Данные
int day;
int month;
int year;
string family;
//Указатель на следующий элемент
Node *next;
//Указатель на предыдущий элемент
Node *prev;
};
//Данные
int day;
int month;
int year;
string family;
//Указатель на следующий элемент
Node *next;
//Указатель на предыдущий элемент
Node *prev;
};
функция main()
Код:
...........................
Node *pbeg, *pend;
//Голова и хвост списка соответственно
..............................
Node *pbeg, *pend;
//Голова и хвост списка соответственно
..............................
Функция формирования первого элемента в списке
Код:
Node [COLOR="red"]*first[/COLOR]( string fio, int day, int month, int year )
[COLOR="Red"]//Функция возвращает указатель, обрати внимание[/COLOR]
{
//Создаем новый элемент типа Node
Node *pv = new Node;
//Заполняем данными
//Значения fio, day и т.д. переменных получаем с клавы либо генерируем в rand()
pv->family = fio;
pv->day = day;
pv->month = month;
pv->year = year;
//Следующего и предыдущих элементов в списке нет, поэтому NULL
pv->next = NULL;
pv->prev = NULL;
//Из функции возвращаем указатель на созданную область памяти
return pv;
}
[COLOR="Red"]//Функция возвращает указатель, обрати внимание[/COLOR]
{
//Создаем новый элемент типа Node
Node *pv = new Node;
//Заполняем данными
//Значения fio, day и т.д. переменных получаем с клавы либо генерируем в rand()
pv->family = fio;
pv->day = day;
pv->month = month;
pv->year = year;
//Следующего и предыдущих элементов в списке нет, поэтому NULL
pv->next = NULL;
pv->prev = NULL;
//Из функции возвращаем указатель на созданную область памяти
return pv;
}
Добавление нового элемента в список
Код:
void add(Node **pend, string fio, int day, int month, int year )
{
Node *pv = new Node;
pv->family = fio;
pv->day = day;
pv->month = month;
pv->year = year;
//Указываем только что созданному элементу, что есть предыдущий
pv->prev = *pend;
//...но нет следующего
pv->next = NULL;
//указываем предыдущему что у него есть следующий
(*pend)->next = pv;
//Последним элементом становиться текущий
*pend = pv;
}
{
Node *pv = new Node;
pv->family = fio;
pv->day = day;
pv->month = month;
pv->year = year;
//Указываем только что созданному элементу, что есть предыдущий
pv->prev = *pend;
//...но нет следующего
pv->next = NULL;
//указываем предыдущему что у него есть следующий
(*pend)->next = pv;
//Последним элементом становиться текущий
*pend = pv;
}
В моей задачи(быстрая сортировка на связном) не надо было вставлять в список новые элементы, только перемещать текущие. Функция для этого ниже. Функция добавления будет выглядеть практически так же, только тебе надо будет передать немного другие параметры, а именно
- какой элемент вставить
- перед каким
- после какого
Код:
void transfer_elem( Node *elem_in, Node *elem_ch, Node **pbeg, Node **pend )
{
// elem_in - элемент, перед которым вставляем elem_ch
// elem_ch - элемент, который переставляем
// pbeg и pend - голова и хвост списка соответственно
// ch_prev, ch_next, in_prev - вспмогаельные указатели
if( elem_ch == (*pend) )
(*pend) = (*pend)->prev;
if( elem_in == (*pbeg) )
(*pbeg) = elem_ch;
Node *ch_prev = elem_ch->prev;
Node *ch_next = elem_ch->next;
Node *in_prev = elem_in->prev;
elem_ch->prev = in_prev;
elem_ch->next = elem_in;
elem_in->prev = elem_ch;
ch_prev->next = ch_next;
if( in_prev != 0 )
in_prev->next = elem_ch;
if( ch_next != 0 )
ch_next->prev = ch_prev;
}
{
// elem_in - элемент, перед которым вставляем elem_ch
// elem_ch - элемент, который переставляем
// pbeg и pend - голова и хвост списка соответственно
// ch_prev, ch_next, in_prev - вспмогаельные указатели
if( elem_ch == (*pend) )
(*pend) = (*pend)->prev;
if( elem_in == (*pbeg) )
(*pbeg) = elem_ch;
Node *ch_prev = elem_ch->prev;
Node *ch_next = elem_ch->next;
Node *in_prev = elem_in->prev;
elem_ch->prev = in_prev;
elem_ch->next = elem_in;
elem_in->prev = elem_ch;
ch_prev->next = ch_next;
if( in_prev != 0 )
in_prev->next = elem_ch;
if( ch_next != 0 )
ch_next->prev = ch_prev;
}
И теперь небольшой ликбез:
указатель любого типа - это 4-ре байта, содержащие [COLOR="red"]только адрес[/COLOR] памяти, в которой хранятся данные(поля день, месяц, год в моей задаче).
Делая
Код:
pbeg->next
ты получаешь [COLOR="Red"]адрес[/COLOR] памяти, которая хранит значения переменных day, month, year следующего узла списка
Код:
pbeg->prev
...предыдущего.
Каждая инструкция
Код:
Node *zz = new Node
создаст указатель(4 байта) на область памяти в 30-100-500-99999... байт, которая будет хранить значения полей структуры.
...а если будет
Код:
Node *zz = new Node [10]
...будет выделена память под (30-100-500-99999...)*10, которая сможет вместить в себя 10 твоих структур
Делая
Код:
Node *apach47 = pbeg->prev
ты создаешь 4 байти(указатель) и присваиваешь в него адрес памяти, в которой находится имя человека, идущего передо мной :)
Можно делать и вот так
Код:
Node *codenet = your_elem
где your_elem - указатель на другую область памяти. Тогда и указатель codenet будет ссылаться на нее же
Свой код прикреплю к этому посту(там быстрая сортировка и бинарный поиск на связном). Буду рад если чем-нибудь поможет
Кроме рекомендую почитать Сэджвика, мне в свое время он несколько помог, особенно в плане алгоритмов
P.S.: если сам не хочешь заморачиваться со связными, хочешь сразу получить готовый код своей лабы - пиши в ЛС, поговорим о цене
Код:
#include <iostream.h>
#include <windows.h>
const int NotUsed=system("color F0");
int menu();
struct list
{
char sn[50]; //student name
int sid; //student number
list *next;
list *prev;
};
list *list_end=NULL; //sozdanie pustogo spiska
list *dobav_nach(list *p); //dobavit v nachalo
list *udal_nach(list *p); //udalit iz nachala
list *dobav_proizv(list *p); //dobavit v proizvolnoe mesto
list *udal_proizv(list *p); //udalit iz proizvolnogo mesta
void proverka(list *p); //proverka, pust li spisok
list *clean_list(list *p); //ochistit spisok
void print(list *p); //vyiti
//------------------------------------------------------------
int main()
{
list *l=NULL;
bool ex=true;
while (ex)
{
switch(menu())
{
case 1:
l=dobav_nach(l);
break;
case 2:
l=udal_nach(l);
break;
case 3:
dobav_proizv(l);
break;
case 4:
if (udal_proizv(l)==NULL)
l=NULL;
break;
case 5:
proverka(l);
break;
case 6:
l=clean_list(l);
break;
case 7:
print(l);
break;
case 0: ex=false;
break;
default: cout<<"Vyberite punkt!"<<endl;
break;
}
}
return 0;
}
//-----------------------------------------------
int menu()
{
int m;
cout<<" --------------------------------"<<endl;
cout<<" Vyberite punkt: \n\n";
cout<<" 1 - dobavit v nachalo\n";
cout<<" 2 - udalit iz nachala\n";
cout<<" 3 - dobavit v proizvolnoe mesto\n";
cout<<" 4 - udalit iz proizvolnogo mesta\n";
cout<<" 5 - proverit, pust li spisok\n";
cout<<" 6 - ochistit spisok\n";
cout<<" 7 - pechat spiska\n";
cout<<" 0 - vyiti\n";
cout<<" --------------------------------"<<endl<<endl;
cin>>m;
return m;
}
//-----------------------------------------------
list *dobav_nach(list *p)
{
list *t;
t=new list;
cout<<endl<<" Vvedite imya studenta: ";
cin>>(t->sn);
cout<<" Vvedite nomer studenta: ";
cin>>t->sid;
if(p==NULL)
{
list_end=t;
t->next=t;
cout<<endl<<" ...Added successfully!\n\n";
}
else
{
t->next=p;
list_end->next=t;
cout<<endl<<" ...Added successfully!\n\n";
}
return t;
}
//-----------------------------------------------
list *udal_nach(list *p)
{
list *t;
if(p==NULL)
cout<<" Spisok pyst!";
else
{
if(p==list_end)
{
delete p;
p=NULL;
list_end=NULL;
cout<<endl<<" ...Deleted successfully!\n\n";
}
else
{
t=p;
p=p->next;
list_end->next=p;
delete t;
cout<<endl<<" ...Deleted successfully!\n\n";
}
}
return p;
}
//-----------------------------------------------
list *dobav_proizv(list *p)
{
int sd;
list *s,*t;
if(p==NULL)
cout<<" Spisok pyst!";
else
{
t=p;
cout<<endl<<"Vvedite nomer studenta, posle kotorogo budet vstavlen etot: ";
cin>>sd;
do
{
if(t->sid==sd)
{
s=new list;
cout<<"Vvedite imya studenta: ";
cin>>(s->sn);
cout<<"Vvedite nomer studenta: ";
cin>>s->sid;
s->next=t->next;
t->next=s;
cout<<endl<<" ...Added successfully!\n\n";
if(s->next==p)
list_end=s;
break;
}
t=t->next;
}
while(t!=p);
}
return s;
}
//-----------------------------------------------
list *udal_proizv(list *p)
{
int sd;
list *s,*t;
if(p==NULL)
cout<<" Spisok pyst!";
else
{
t=p;
cout<<endl<<"Vvedite nomer studenta, kotoruy budet udalen: ";
cin>>sd;
while(t->next!=p)
{
if(t->next->sid==sd)
{
s=t->next;
t->next=s->next;
delete s;
cout<<endl<<" ...Deleted successfully!\n\n";
if(t->next==p)
{
list_end=t;
}
break;
}
t=t->next;
}
}
return t;
}
//-----------------------------------------------
void proverka(list *p)
{
if(p==NULL)
cout<<endl<<" Spisok pyst!\n\n";
else
cout<<endl<<" Spisok ne pyst!\n\n";
}
//-----------------------------------------------
list *clean_list(list *p)
{
list *t;
if(p==NULL)
cout<<" Spisok pyst!";
else
{
while(p!=list_end)
{
t=p;
p=p->next;
delete t;
}
delete p;
p=NULL;
list_end=NULL;
cout<<endl<<" ...Cleaned successfully!\n\n";
}
return p;
}
//-----------------------------------------------
void print(list *p)
{
list *t_p=p;
if(t_p)
{
do
{
cout<<" ---------------------------"<<endl;
cout<<" Imya studenta: "<<t_p->sn<<endl;
cout<<" Nomer studenta: "<<t_p->sid<<endl;
cout<<" ---------------------------\n\n";
t_p=t_p->next;
}
while(t_p!=list_end->next);
}
else
cout<<" Spisok pyst!\n\n";
}
#include <windows.h>
const int NotUsed=system("color F0");
int menu();
struct list
{
char sn[50]; //student name
int sid; //student number
list *next;
list *prev;
};
list *list_end=NULL; //sozdanie pustogo spiska
list *dobav_nach(list *p); //dobavit v nachalo
list *udal_nach(list *p); //udalit iz nachala
list *dobav_proizv(list *p); //dobavit v proizvolnoe mesto
list *udal_proizv(list *p); //udalit iz proizvolnogo mesta
void proverka(list *p); //proverka, pust li spisok
list *clean_list(list *p); //ochistit spisok
void print(list *p); //vyiti
//------------------------------------------------------------
int main()
{
list *l=NULL;
bool ex=true;
while (ex)
{
switch(menu())
{
case 1:
l=dobav_nach(l);
break;
case 2:
l=udal_nach(l);
break;
case 3:
dobav_proizv(l);
break;
case 4:
if (udal_proizv(l)==NULL)
l=NULL;
break;
case 5:
proverka(l);
break;
case 6:
l=clean_list(l);
break;
case 7:
print(l);
break;
case 0: ex=false;
break;
default: cout<<"Vyberite punkt!"<<endl;
break;
}
}
return 0;
}
//-----------------------------------------------
int menu()
{
int m;
cout<<" --------------------------------"<<endl;
cout<<" Vyberite punkt: \n\n";
cout<<" 1 - dobavit v nachalo\n";
cout<<" 2 - udalit iz nachala\n";
cout<<" 3 - dobavit v proizvolnoe mesto\n";
cout<<" 4 - udalit iz proizvolnogo mesta\n";
cout<<" 5 - proverit, pust li spisok\n";
cout<<" 6 - ochistit spisok\n";
cout<<" 7 - pechat spiska\n";
cout<<" 0 - vyiti\n";
cout<<" --------------------------------"<<endl<<endl;
cin>>m;
return m;
}
//-----------------------------------------------
list *dobav_nach(list *p)
{
list *t;
t=new list;
cout<<endl<<" Vvedite imya studenta: ";
cin>>(t->sn);
cout<<" Vvedite nomer studenta: ";
cin>>t->sid;
if(p==NULL)
{
list_end=t;
t->next=t;
cout<<endl<<" ...Added successfully!\n\n";
}
else
{
t->next=p;
list_end->next=t;
cout<<endl<<" ...Added successfully!\n\n";
}
return t;
}
//-----------------------------------------------
list *udal_nach(list *p)
{
list *t;
if(p==NULL)
cout<<" Spisok pyst!";
else
{
if(p==list_end)
{
delete p;
p=NULL;
list_end=NULL;
cout<<endl<<" ...Deleted successfully!\n\n";
}
else
{
t=p;
p=p->next;
list_end->next=p;
delete t;
cout<<endl<<" ...Deleted successfully!\n\n";
}
}
return p;
}
//-----------------------------------------------
list *dobav_proizv(list *p)
{
int sd;
list *s,*t;
if(p==NULL)
cout<<" Spisok pyst!";
else
{
t=p;
cout<<endl<<"Vvedite nomer studenta, posle kotorogo budet vstavlen etot: ";
cin>>sd;
do
{
if(t->sid==sd)
{
s=new list;
cout<<"Vvedite imya studenta: ";
cin>>(s->sn);
cout<<"Vvedite nomer studenta: ";
cin>>s->sid;
s->next=t->next;
t->next=s;
cout<<endl<<" ...Added successfully!\n\n";
if(s->next==p)
list_end=s;
break;
}
t=t->next;
}
while(t!=p);
}
return s;
}
//-----------------------------------------------
list *udal_proizv(list *p)
{
int sd;
list *s,*t;
if(p==NULL)
cout<<" Spisok pyst!";
else
{
t=p;
cout<<endl<<"Vvedite nomer studenta, kotoruy budet udalen: ";
cin>>sd;
while(t->next!=p)
{
if(t->next->sid==sd)
{
s=t->next;
t->next=s->next;
delete s;
cout<<endl<<" ...Deleted successfully!\n\n";
if(t->next==p)
{
list_end=t;
}
break;
}
t=t->next;
}
}
return t;
}
//-----------------------------------------------
void proverka(list *p)
{
if(p==NULL)
cout<<endl<<" Spisok pyst!\n\n";
else
cout<<endl<<" Spisok ne pyst!\n\n";
}
//-----------------------------------------------
list *clean_list(list *p)
{
list *t;
if(p==NULL)
cout<<" Spisok pyst!";
else
{
while(p!=list_end)
{
t=p;
p=p->next;
delete t;
}
delete p;
p=NULL;
list_end=NULL;
cout<<endl<<" ...Cleaned successfully!\n\n";
}
return p;
}
//-----------------------------------------------
void print(list *p)
{
list *t_p=p;
if(t_p)
{
do
{
cout<<" ---------------------------"<<endl;
cout<<" Imya studenta: "<<t_p->sn<<endl;
cout<<" Nomer studenta: "<<t_p->sid<<endl;
cout<<" ---------------------------\n\n";
t_p=t_p->next;
}
while(t_p!=list_end->next);
}
else
cout<<" Spisok pyst!\n\n";
}
пожалуйста подскажите, как сделать что бы имя студента можно было записывать с пробелами, а так же что бы номер был максимум 10 символов. и еще интересует, правильно ли вообще составлен "кольцевой двунаправленный список", и что здесь не так?