Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Двусвязный линейный список, Добавление элементов 
V
    Опции темы
Stelz
Дата 30.11.2007, 21:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 31.7.2007

Репутация: нет
Всего: нет



Есть структура book и структура deck. Способ реализации - связанный двунаправленный линейный список. Необходимо осуществить добавление элемента справа и добавление элемента слева.

Код

#include <conio.h>
#include <iostream.h>
#include <string.h>

struct book
{
        char author[20];
        char title[20];
        int year;
};

struct element
{
        book info;
        element *next;
        element *prev;
};

void add_next(element *&deck, book x);
void add_prev(element *&deck, book x);

void main(){

        element *deck = 0;
        
        book x;
        bool OK;
        int p;

do {
                clrscr();

                cout<<"1.Vvod knigi v nachalo decka"<<endl;
                cout<<"2.Vvod knigi v konec decka"<<endl;
                cout<<"3.Exit"<<endl<<endl;
                cout<<"Select option ";
                cin>>p;

                switch (p) {
                        case 1:
                        cout<<"Add book sleva"<<endl;
                        cout<<"Author: ";
                        cin.get();
                        cin.getline(x.author,20);
                        cout<<"Title: ";
                        cin.get();
                        cin.getline(x.title,20);
                        cout<<"Year: ";
                        cin>>x.year;
                        add_prev(deck,x);
                        cout<<"Vipolneno uspeshno"<<endl;
                        break;

                        case 2:
                        cout<<"Add book sprava"<<endl;
                        cout<<"Author: ";
                        cin.get();
                        cin.getline(x.author,20);
                        cout<<"Title: ";
                        cin.get();
                        cin.getline(x.title,20);
                        cout<<"Year: ";
                        cin>>x.year;
                        add_end(deck,x);
                        cout<<"Vipolneno uspeshno"<<endl;
                        break;
                }
        getch();
        }
        while(p!=3)};
}
void add_next(element*&deck, book x)
{
element *p;
p=new element;
p->info=x;
p->next=deck;
deck=p;
}
void add_prev(element*&deck, book x)
{

}



Функцию add_next взял из работы с односвязным списком... Осуществить вставку справа и слева с двусвязным списком не получается, ибо плохо разбираюсь с указателями, необходима помощь. Заранее благодарен.
PM MAIL   Вверх
bsa
Дата 30.11.2007, 22:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Лучше ввести еще одну служебную структуру, по которой и будет производиться работа (это намного удобней и быстрей в общем случае,  чем работа напрямую со списком, определяемым указателем на первый элемент):
Код
struct list
{
     element *first;
     element *last;
     list() { first = 0; last = 0; } //это конструктор, который нужен, чтобы поля first и last были валидными
};
Функции для работы со списком:
Код
element* add_prev(list &lst, const book &b)
{
     element *t = new element;
     t->info = b;
     t->prev = 0;
     t->next = lst.first;
     lst.first = t;
     return t;
}
element* add_next(list &lst, const book &b)
{
     element *t = new element;
     t->info = b;
     t->prev = lst.last;
     t->next = 0;
     lst.last = t;
     return t;
}
element* insert_after(list &lst, element *pos, const book &b) //вставляет новый элемент за элементом pos в списке lst
{
     element *t = new element;
     t->info = b;
     t->prev = pos;
     t->next = pos->next;
     pos->next = t;
     if ( !t->next ) //если pos был последним элементом списка (скорее всего)
         lst.last = t;  //то обновляем поле last списка
     return t;
}
element* insert_before(list &lst, element *pos, const book &b) //вставляет новый элемент перед элементом pos в списке lst
{
     element *t = new element;
     t->info = b;
     t->prev = pos->prev;
     t->next = pos;
     pos->prev = t;
     if ( !t->prev ) //если pos был первым элементом списка (скорее всего)
         lst.first = t;  //то обновляем поле first списка
     return t;
}
void clear_list(list &lst) //можно сделать в виде деструктора класса list
{
      for(element *t1 = lst.first, *t2; t1; t1 = t2) {
           t2 = t1->next;
           delete t1;
      }
      lst.first = 0;
      lst.last = 0;
}


Это сообщение отредактировал(а) bsa - 1.12.2007, 11:43
PM   Вверх
Stelz
Дата 1.12.2007, 01:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 31.7.2007

Репутация: нет
Всего: нет



t->next = lst->first ; E2288 Pointer to structure required on left side of -> or ->*

t->prev = lst->last; E2288 Pointer to structure required on left side of -> or ->*

for(element *t1 = lst.first, t2; t1; t1 = t2) { E2034 Cannot convert 'element' to 'element *'

t2 = t1->next; [C++ Error] Unit1.cpp(75): E2034 Cannot convert 'element *' to 'element'


[C++ Warning] Unit1.cpp(77): W8004 't2' is assigned a value that is never used

Простите, если глупые вопросы, но в СИ я плохо пока соображаю. Если последние 2 ошибки подозреваю исправляются простановкой * перед t2, то как исправить первые, непонятно.

Если можно еще поясните, на примере, как мне из main() добавить запись слева и справа и потом вывести все записи, теперь как я понял в параметрах при вызове функции указывается уже не deck... 

И еще, нужны ли прототипы для данных функций и, если да, то как их объявить правильно.
Заранее благодарю за ответ.
PM MAIL   Вверх
0lmer
Дата 1.12.2007, 07:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 115
Регистрация: 3.12.2006

Репутация: нет
Всего: -1



Шаблон класса двусвязного списка, то что отмечено "+" работает правильно smile Вроде.
Смотри, мож пригодится...

Код

template <class Type>
class T2Spisok {
private:
/***********************/
/**/  class TNode {            /**/
/**/  public:                        /**/
/**/    Type data;               /**/
/**/    TNode * pred;          /**/
/**/    TNode * next;          /**/
/**/    int index;                 /**/
/**/    TNode() : pred(0),   /**/
/**/              next(0),         /**/
/**/              index(0) {}   /**/
/**/  };                              /**/
/***********************/
  TNode * begin;
  TNode * end;
  TNode * current;
  unsigned int length;
  void SortIndex();
public:
  T2Spisok();                                //Konstruktor po umolchaniyu. +
  T2Spisok(T2Spisok<Type> & _spisok);  //Konstruktor kopirovaniya. +
  ~T2Spisok();             //Destruktor; +
  void SetToBegin();       //Ustanovka ukazatelya na nachalo. +
  void SetToEnd();         //Ustanovka ukazatelyu na konec. +
  void GoNext();           //Sled. element. +
  void GoPred();           //Pred. element. +
  bool IsBegin() const;    //Tekuchii == begin?. +
  bool IsEnd() const;      //Tekuchii == end?. +
  bool IsNull() const;     //Current == 0?. +
  bool IsEmpty() const;    //True esli spisok pust. +
  unsigned int GetLength() const;        //Vozvrachaet kol-vo elementov. +
  unsigned int GetCurrentIndex() const throw (char *);   //Vozvray indeksa tekushego elementa. +
  void Clear();                                          //Ochistka spiska. +
  void operator=(const T2Spisok<Type> & _spisok);        //Kopirovanie spiskov. +
  Type & operator[](unsigned int _index) throw (char *); //Dostup po indeksu. +
  Type & GetCurrentData() const throw (char *);          //Vozvrat ssylki na tekushie dannye. +
  Type * GetCurrentDataPtr() const throw (char *);       //Vozvrat adresa dannyh. +
  void AddToBegin(const Type & _data);                   //Dobavlenie elementa v nachalo. +
  void AddToEnd(const Type & _data);                     //Dobavlenie elementa v konec. +
  void DeleteIndex(const unsigned int _index) throw (char *); //Udalenie elementa po indeksu. +
  void DeleteCurrent() throw (char *);                        //Udalenie tekushego elementa. 
  void AddAfterCurrent(const Type & _data) throw (char *);    //Dobavlenie posle tekushego.
  void AddBeforeCurrent(const Type & _data) throw (char *);   //Dobavlenie do tekushego. 
};

//Sortirovka indeksov;
template <class Type>
void T2Spisok<Type>::SortIndex() {
  int i;
  for (i = 0, this->current = this->begin; this->current != 0; this->current = this->current->next, ++i) {
    this->current->index = i;
  }
  this->current = this->begin; 
}  

//Konstruktor po umolchaniyu.
template <class Type>
T2Spisok<Type>::T2Spisok() {
  this->begin = 0;
  this->end = 0;
  this->current = 0;
  this->length = 0;
}

//Konstruktor kopirovaniya.
template <class Type>
T2Spisok<Type>::T2Spisok(T2Spisok<Type> & _spisok) {
  this->begin = 0;
  this->end = 0;
  this->current = 0;
  this->length = 0;
  for (_spisok.SetToBegin(); !_spisok.IsNull(); _spisok.GoNext()) {
    this->AddToEnd(_spisok.current->data);
  }
  _spisok.SetToBegin();
  this->current = this->begin;
}

//Destruktor.
template <class Type>
T2Spisok<Type>::~T2Spisok() {
  while (this->begin != this->end) {
    this->current = this->begin->next;
    delete this->begin;
    this->begin = this->current;
  } 
}

//Ustanovka ukaz. na nachalo.
template <class Type>
void T2Spisok<Type>::SetToBegin() {
  this->current = this->begin;
}

//Ustanovka ukaz. v konec.
template <class Type>
void T2Spisok<Type>::SetToEnd() {
  this->current = this->end;
}

//Vpered.
template <class Type>
void T2Spisok<Type>::GoNext() {
  this->current = this->current->next;
}

//Nazad.
template <class Type>
void T2Spisok<Type>::GoPred() {
  this->current = this->current->pred;
}

//IsBegin?
template <class Type>
bool T2Spisok<Type>::IsBegin() const {
  if (this->current == this->begin) {
    return true;
  } else {
    return false;
  }    
} 

//IsEnd?
template <class Type>
bool T2Spisok<Type>::IsEnd() const {
  if (this->current == this->end) {
    return true;
  } else {
    return false;
  }    
} 

//Current == 0?
template <class Type>
bool T2Spisok<Type>::IsNull() const {
  if (this->current == 0) {
    return true;
  } else {
    return false;
  }   
}  

//Spisok pust?
template <class Type>
bool T2Spisok<Type>::IsEmpty() const {
  if (this->length == 0) {
    return true;
  } else {
    return false;
  }    
}

//Vozvrat dliny.
template <class Type>
unsigned int T2Spisok<Type>::GetLength() const {
  return this->length;
} 

//Vozvrat indeksa tekushego elementa.
template <class Type>
unsigned int T2Spisok<Type>::GetCurrentIndex() const throw (char *) {
  if (this->current == 0) {
    throw "ERROR!!! Ukazatel\' na tekushii element == 0!!!";
  }  
  return this->current->index;
}

//Ochistka spiska.
template <class Type>
void T2Spisok<Type>::Clear() {
  while (this->begin != this->end) {
    this->current = this->begin->next;
    delete this->begin;
    this->begin = this->current;
  }  
  delete this->end;
  this->begin = 0;
  this->current = 0;
  this->end = 0;
  this->length = 0;
} 

//Kopirovanie spiskov.
template <class Type>
void T2Spisok<Type>::operator=(const T2Spisok<Type> & _spisok) {
  this->Clear();
  for (_spisok.SetToBegin(); !_spisok.IsNull(); _spisok.GoNext()) {
    this->AddToEnd(_spisok.current->data);
  }
  _spisok.SetToBegin();
  this->current = this->begin;
} 

//Dostup po indeksu.
template <class Type>
Type & T2Spisok<Type>::operator[](unsigned int _index) throw (char *) {
  if (_index >= this->length || _index < 0) {
    throw "ERROR!!! Nepravil\'nyi index!!!";
  } else {
    for (this->current = this->begin; this->current->index != _index; this->current = this->current->next);
    return this->current->data; 
  }  
}

//Vozvrat dannyh.
template <class Type>
Type & T2Spisok<Type>::GetCurrentData() const throw (char *) {
  if (this->current == 0) {
    throw "ERROR!!! Ukazatel\' na tekushii element == 0!!!";
  }  
  return this->current->data;
} 

//Vozvrat ukazatelya na dannye.
template <class Type>
Type * T2Spisok<Type>::GetCurrentDataPtr() const throw (char *) {
  if (this->current == 0) {
    throw "ERROR!!! Ukazatel\' na tekushii element == 0!!!";
  } 
  return &(this->current->data);
}  

//Dobavlenie v nachalo spiska.
template <class Type>
void T2Spisok<Type>::AddToBegin(const Type & _data) {
  TNode * node = new TNode();
  node->data = _data;
  if (this->length == 0) {
    this->begin = this->end = node;
  } else {
    node->pred = 0;
    node->next = this->begin;
    this->begin->pred = node;
    this->begin = node;
  }  
  ++length;  
  this->SortIndex();
  this->current = this->begin;
} 

//Dobavlenie v konec.
template <class Type>
void T2Spisok<Type>::AddToEnd(const Type & _data) {
  TNode * node = new TNode();
  node->data = _data;
  if (this->length == 0) {
    this->begin = this->end = node;
  } else {
    node->next = 0;
    node->pred = this->end;
    this->end->next = node;
    this->end = node;
  }  
  ++length;  
  this->SortIndex();
  this->current = this->begin;
}   

//Udalenie po indexu.
template <class Type>
void T2Spisok<Type>::DeleteIndex(const unsigned int _index)  throw (char *) {
  if (_index < 0 || _index >= this->length) {
    throw "ERROR!!! Nepravil\'nyi index!!!";
  }  
  if (this->length == 1) {
    delete this->begin;
    this->begin = 0;
    this->end = 0;
    --this->length;
    this->SortIndex();
    return;
  }  
  if (_index == 0) { //Udalit' begin.
    this->begin->next->pred = 0;
    this->current = this->begin;
    this->begin = this->current->next;
    delete this->current;
    --this->length;
    this->SortIndex();
    return;
  }  
  if (_index == this->length - 1) { //Udalit' end.
    this->end->pred->next = 0;
    this->current = this->end;
    this->end = this->current->pred;
    delete this->current;
    --this->length;
    this->SortIndex();
    return;
  } 
  for (this->current = this->begin; this->current->index != _index; this->current = this->current->next);
  this->current->next->pred = this->current->pred;
  this->current->pred->next = this->current->next;
  delete this->current;
  --this->length;
  this->SortIndex();
  this->current = this->begin;      
}  

//Udalenie tekushego elementa.
template <class Type>
void T2Spisok<Type>::DeleteCurrent() throw (char *) {
  if (this->current == 0) {
    throw "ERROR!!! Ukazatel\' na tekushii element == 0!!!";
  }  
  if (this->length == 1) {
    delete this->begin;
    this->begin = 0;
    this->end = 0;
    --this->length;
    this->SortIndex();
    return;
  }  
  if (this->current == this->begin) { //Udalit' begin.
    this->begin->next->pred = 0;
    this->begin = this->current->next;
    delete this->current;
    --this->length;
    this->SortIndex();
    return;
  }
  if (this->current == this->end) { //Udalit' end.
    this->end->pred->next = 0;
    this->end = this->current->pred;
    delete this->current;
    --this->length;
    this->SortIndex();
    return;
  } 
  this->current->next->pred = this->current->pred;
  this->current->pred->next = this->current->next;
  delete this->current;
  --this->length;
  this->SortIndex();
  this->current = this->begin;  
} 

//Dobavlenie posle tekushego.
template <class Type>
void T2Spisok<Type>::AddAfterCurrent(const Type & _data) throw (char *) {
  if (this->current == 0) {
    throw "ERROR!!! Ukazatel\' na tekushii element == 0!!!";
  }
  if (this->current == this->end) {
    this->AddToEnd(_data);
    return;
  }
  TNode * node = new TNode();
  node->data = _data;
  node->pred = this->current;
  node->next = this->current->next;
  this->current->next->pred = node;
  this->current->next = node;
  ++length;
  this->SortIndex();
  this->current = this->begin;
} 

//Dobavlenie pered tekushim.
template <class Type>
void T2Spisok<Type>::AddBeforeCurrent(const Type & _data) throw (char *) {
  if (this->current == 0) {
    throw "ERROR!!! Ukazatel\' na tekushii element == 0!!!";
  }
  if (this->current == this->begin) {
    this->AddToBegin(_data);
    return;
  }
  TNode * node = new TNode();
  node->data = _data;
  node->pred = this->current->pred;
  node->next = this->current;
  this->current->pred->next = node;
  this->current->pred = node;
  ++length;
  this->SortIndex();
  this->current = node;
}   

PM   Вверх
Dims
Дата 1.12.2007, 08:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1016
Регистрация: 21.11.2006

Репутация: 1
Всего: 11



Указатель -- это просто адрес. То есть, число, представляющее собой порядковый номер ячейки памяти. В смысле, так можно думать.

Ну вот, исправляю и вставляю комментарии

Код

// каждый элемент списка содержит
struct element
{
        // информацию о книжке 
        book info;
        
        // адрес следующего элемента
        element *next;

        // адрес предыдущего элемента
        element *prev;
};
// обычно договариваются, что крайние звенья содержат в этих полях NULL
// если звено единственное, то NULL лежит в обоих полях

// чтобы добавить звено ПОСЛЕ звена deck и положить в него информацию x и вернуть адрес нового звена, надо
void add_next(element*&deck, book x)
{

   // завести переменную для адреса
   element *p;

   // создать новое звено и положить его адрес в эту переменную
   p=new element;

   // заполнить информацию
   p->info=x;

   // в новосозданном звене установить адрес предыдущего на переданное
   p->prev = deck;

   // в новосозданном звене установить адрес следующего на тот, который был следующим в переданном (чтобы цепочка не уводила в никуда!)
   p->next = deck->next;

   // в переданном звене установить адрес следующего на новосозданное
   deck->next=p;

   // положить в ссылку адрес новосозданного звена, чтобы вызывающая программа могла его прочитать
   deck = p;
}

PM MAIL   Вверх
bsa
Дата 1.12.2007, 11:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Stelz, я действительно в 3-х местах опечатался. В частности, все "lst->" надо заменить на "lst." и перед t2 поставить звездочку.
Как с этим работать:
Код
int main()
{
     list lst;
     book b;
     ....
     add_next(lst, b);
     ....
     element *p = add_prev(lst, b);
     ....
     p = insert_before(lst, p, b);
     ....
     insert_after(lst, p, b);
     ....
     clear_list(lst);
     ....
     return 0;
}
Проще, по-моему, только если полностью через ООП реализовать.
PM   Вверх
Stelz
Дата 1.12.2007, 13:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 31.7.2007

Репутация: нет
Всего: нет



Код

lement* add_prev(list &lst, const book &b)
{
     element *t = new element;
     t->info = b;
     t->prev = 0;
     t->next = lst.first ;
     lst.first = t;
     return t;
}
element* add_next(list &lst, const book &b)
{
     element *t = new element;
     t->info = b;
     t->prev = lst.last;
     t->next = 0;
     lst.last = t;
     return t;
}
element* insert_after(list &lst, element *pos, const book &b) //вставляет новый элемент за элементом pos в списке lst
{
     element *t = new element;
     t->info = b;
     t->prev = pos;
     t->next = pos->next;
     pos->next = t;
     if ( !t->next ) //если pos был последним элементом списка (скорее всего)
         lst.last = t;  //то обновляем поле last списка
     return t;
}
element* insert_before(list &lst, element *pos, const book &b) //вставляет новый элемент перед элементом pos в списке lst
{
     element *t = new element;
     t->info = b;
     t->prev = pos->prev;
     t->next = pos;
     pos->prev = t;
     if ( !t->prev ) //если pos был первым элементом списка (скорее всего)
         lst.first = t;  //то обновляем поле first списка
     return t;
}
void clear_list(list &lst) //можно сделать в виде деструктора класса list
{
      for(element *t1 = lst.first, *t2; t1; t1 = t2) {
           t2 = t1->next;
           delete t1;
      }
      lst.first = 0;
      lst.last = 0;
}

void print(list &lst)
{
      for(element *t1 = lst.first, *t2; t1; t1 = t2) {
           t2 = t1->next;
           cout <<"Author: "<< t1->info.author <<"; ";
        cout <<"Title: "<< t1->info.title <<"; ";
        cout <<"Year: "<< t1->info.year <<"; "<<endl;
      }

void main(){


          list lst;
        book b;

        bool OK;
        int p1;

        do {
                clrscr();

                cout<<"1.Vvod knigi sleva"<<endl;
                cout<<"2.Vvod knigi sprava"<<endl;
                cout<<"3.Print list"<<endl<<endl;
                cout<<"4.Exit"<<endl<<endl;
                cout<<"Select option ";
                cin>>p1;

                element *p;
                        p = new element;

                switch (p1) {
                        case 1:

                        cout<<"Add book sleva"<<endl;
                        cout<<"Author: ";
                        cin.get();
                        cin.getline(b.author,20);
                        cout<<"Title: ";
                        cin.get();
                        cin.getline(b.title,20);
                        cout<<"Year: ";
                        cin>>b.year;
                        p=add_prev(lst, b);
                        cout<<"Vipolneno uspeshno"<<endl; 
                        break;

                        case 2:

                        cout<<"Add book sprava"<<endl;
                        cout<<"Author: ";
                        cin.get();
                        cin.getline(b.author,20);
                        cout<<"Title: ";
                        cin.get();
                        cin.getline(b.title,20);
                        cout<<"Year: ";
                        cin>>b.year;
                        p=add_next(lst, b);
                        cout<<"Vipolneno uspeshno"<<endl;   
                        break;

                        case 3:

                        cout<<"Prosmotr knig"<<endl;
                        print(lst);
                        break;
                }
        getch();
        }
        while(p1!=4);
}


Не работает add_next. Так же не совсем понял как при insert_before и insert_after установить указатель на последний элемент к примеру. И правильно ли я функцию принт сделал?
PM MAIL   Вверх
bsa
Дата 1.12.2007, 13:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Stelz, а на что тебе отладчик?
На самом деле и add_next, add_prev работают одинакого неправильно. чтобы они работали правильно надо в них добавить следующие строки перед return t;:
в add_next():
Код
     if (!lst.first)
        lst.first = t;
в add_prev():
Код
     if (!lst.last)
        lst.last = t;

PM   Вверх
Stelz
Дата 1.12.2007, 13:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 31.7.2007

Репутация: нет
Всего: нет



Все ранво add_next() не добавляет записи. Добавляю адд_превом3 записи, вывожу на принт, добавились, после добавляю некстом, вывожу на принт, никаких изменений(
PM MAIL   Вверх
bsa
Дата 1.12.2007, 13:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Stelz, проверь, ты туда ли поместил указанные мной строчки.
Кстати, print() логичнее сделать так:
Код
void print(const list &lst)
{
      for(const element *t = lst.first; t; t = t->next) {
           cout <<"Author: "<< t->info.author <<"; ";
           cout <<"Title: "<< t->info.title <<"; ";
           cout <<"Year: "<< t->info.year <<"; "<<endl;
      }
}


Добавлено через 11 минут и 12 секунд
Точно. есть такая ошибка - забыл обновлять поля существующего элемента:
Код
element* add_prev(list &lst, const book &b)
{
     element *t = new element;
     t->info = b;
     t->prev = 0;
     t->next = lst.first;
     if (lst.first)
        lst.first->prev = t;
     lst.first = t;
     if (!lst.last)
        lst.last = t;
     return t;
}
element* add_next(list &lst, const book &b)
{
     element *t = new element;
     t->info = b;
     t->prev = lst.last;
     t->next = 0;
     if (lst.last)
        lst.last->next = t;
     lst.last = t;
     if (!lst.first)
        lst.first = t;
     return t;
}
У insert'ов та же проблема.
PM   Вверх
Stelz
Дата 1.12.2007, 14:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 31.7.2007

Репутация: нет
Всего: нет



Код

//---------------------------------------------------------------------------


#include <conio.h>
#include <iostream.h>
#include <string.h>

struct book
{
        char author[20];
        char title[20];
        int year;
};

struct element
{
        book info;
        element *next;
        element *prev;
};

struct list
{
     element *first;
     element *last;
     list() { first = 0; last = 0; } //это конструктор, который нужен, чтобы поля first и last были валидными
};
//---------------------------------------------------------------------------


void print(const list &lst)
{
      for(const element *t = lst.first; t; t = t->next) {
           cout <<"Author: "<< t->info.author <<"; ";
           cout <<"Title: "<< t->info.title <<"; ";
           cout <<"Year: "<< t->info.year <<"; "<<endl;
      }
}

element* add_prev(list &lst, const book &b)
{
     element *t = new element;
     t->info = b;
     t->prev = 0;
     t->next = lst.first ;
     lst.first = t;
     if (!lst.last)
        lst.last = t;
     return t;
}
element* add_next(list &lst, const book &b)
{
     element *t = new element;
     t->info = b;
     t->prev = lst.last;
     t->next = 0;
     lst.last = t;
     if (!lst.first)
        lst.first = t;
     return t;
}

void main(){


          list lst;
        book b;

        bool OK;
        int p1;

        do {
                clrscr();

                cout<<"1.Vvod knigi sleva"<<endl;
                cout<<"2.Vvod knigi sprava"<<endl;
                cout<<"3.Prosmotr knig"<<endl;
                cout<<"4.Exit"<<endl;
                cout<<"Select option ";
                cin>>p1;

                element *p;
                        //p = new element;

                switch (p1) {
                        case 1:

                        cout<<"Add book sleva"<<endl;
                        cout<<"Author: ";
                        cin.get();
                        cin.getline(b.author,20);
                        cout<<"Title: ";
                        cin.get();
                        cin.getline(b.title,20);
                        cout<<"Year: ";
                        cin>>b.year;
                        p=add_prev(lst, b);
                        cout<<"Vipolneno uspeshno"<<endl; 
                        break;

                        case 2:

                        cout<<"Add book sleva"<<endl;
                        cout<<"Author: ";
                        cin.get();
                        cin.getline(b.author,20);
                        cout<<"Title: ";
                        cin.get();
                        cin.getline(b.title,20);
                        cout<<"Year: ";
                        cin>>b.year;
                        p= add_next(lst, b);
                        cout<<"Vipolneno uspeshno"<<endl;   
                        break;

                        case 3:
                        cout<<"Prosmotr knig"<<endl;
                        print(lst);
                        break;

                }
        getch();
        }
        while(p1!=4);
}



Штука такая, что если добавить add_next()ом первый элемент, то он его добавит и дальше этой функцией уже ничего не добавляется, а add_prev()ом нормально добавлятся всё... Если же первый элемент добавить add_prev() то add_next() далее уже ничего не добавляет.
PM MAIL   Вверх
bsa
Дата 1.12.2007, 14:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Stelz, читай выше
PM   Вверх
Stelz
Дата 1.12.2007, 14:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 31.7.2007

Репутация: нет
Всего: нет



Огромное спасибо. Последний небольшой вопрос, как осуществить удаление только последнего элемента списка?
Пытаюсь сделать по аналогии с clear_list(), но толи указатель неправильно сдвигаю, толи еще что-то, ибо вместо удаления, элемент выводится с данными в виде крякозябр)
PM MAIL   Вверх
bsa
Дата 1.12.2007, 15:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Stelz, ты должен сделать примерно это:
Код

element *t = lst.last->prev;
delete lst.last;
lst.last = t;
t->next = 0;
Здесь нет проверки на пустой список и список, содержащий 1 элемент.

PM   Вверх
Stelz
Дата 1.12.2007, 15:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 31.7.2007

Репутация: нет
Всего: нет



Огромное спасибо
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.2089 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.