Страница 1 из 1

Класс Queue

Добавлено: 11 мар 2010, 13:47
Dragon
Класс Queue реализовал следующим образом:
- добавление нового элемента производится в конец списка
- удаление такое же, как и в классе Stack

Проблема в добавлении в очередь.
Вне класса код работает корректно, а в классе программа при вызове add(*значение*) вылетает с ошибкой. Дебаггер ничего толкового не подсказал.
Код добавления в очередь:

Код: Выделить всё

void Queue::add(char the_symbol)
    {
        QueueFramePtr temp; //QueueFramePtr - указатель на структуру с узлом списка
        temp = new QueueFrame;
        temp->data = the_symbol; //data хранит в себе данные типа char
        temp->link = NULL; //link - QueueFrame указатель на следующий узел
        head->link = temp; //head - переменная-указатель класса Queue на структуру QueueFrame.

        //Добавление как в стеке проблем не вызывает
        /*temp->link = head;
        head = temp;*/
    }
Дебаггер завершает все сигналом SIGSEGV и ссылается на последнюю строку: head->link = temp;

Re: Класс Queue

Добавлено: 11 мар 2010, 14:01
Albor
Ты изменяешь head->link, а если в очереди больше 2х элементов? Нужно в классе хранить указатель на хвост списка. В QueueFrame можно вставить конструктор с параметром типа char, где обнулить link и запомнить символ, тогда метод add будет выглядеть лучше - типа такого

Код: Выделить всё

tail->link=new QueueFrame (the_symbol);
tail=tail->link;

Re: Класс Queue

Добавлено: 11 мар 2010, 14:03
Romeo
Значит ты не там смотрел, если дебагер толкового ничего не подсказал. Чему равно значение head перед выполнением строки кода head->link = temp? Скорее всего NULL и именно поэтому его разыменование даёт тебе сингал.

Ко всему прочему неверен сам подход. Для того, чтобы добавить новый элемент в хвост, нужно пробежать от головы до последнего ненулевого элента (то есть хвостового) и проставить у него link на твой temp, а не пытаться переписывать link у head. Альтернативный вариант (чтобы каждый раз не бегать в поисках хвоста), это завести в классе дополнительное поле tail и хранить адрес последнего элемента списка в нём.

Re: Класс Queue

Добавлено: 11 мар 2010, 15:16
Dragon
Спасибо, понял свою ошибку (надо привыкать к тому, что в списках лучше держать запасной указатель на конец списка).

В интерфейс класса добавил указатель tail, который в конструкторе по-умолчанию инициализируется значением head (т.е. NULL).

Функция add стала такой:

Код: Выделить всё

void Queue::add(char the_symbol)
    {
        if(empty())
        {
            QueueFramePtr temp;
            temp = new QueueFrame;
            temp->data = the_symbol;
            temp->link = tail;
            head = temp;
            tail = head;
        }
        else
        {
            QueueFramePtr temp;
            temp = new QueueFrame;
            temp->data = the_symbol;
            temp->link = NULL;
            tail->link = temp;
            tail = tail->link;
        }
    }
Теперь все работает как часы.

Albor
tail->link=new QueueFrame (the_symbol);
tail=tail->link;
По-моему это аналог, написанного выше, за исключением того, что нужно создать доп. конструктор с одним параметром. НО он может быть очень даже полезным, как следствие код красивее становится, да и не менее простым :)

Re: Класс Queue

Добавлено: 11 мар 2010, 15:53
Albor
Dragon, держи для начала пример

Код: Выделить всё

struct QueueFrame
{
 QueueFrame  * pLink;
 char data;
 QueueFrame (char d)
 {
  data=d;
  pLink=0;
 }
};
class Queue
{
 QueueFrame * m_pHead;
 QueueFrame * m_pTail;
public:
 Queue():m_pHead(NULL),m_pTail(NULL) {}
 ~Queue()
 {
  while(m_pHead)
  {
   QueueFrame * p=m_pHead->pLink;
   delete m_pHead;
   m_pHead=p;
  }
 }
 void Add(char sym)
 {
  if(m_pHead!=NULL)
  {
   m_pTail->pLink=new QueueFrame(sym);
   m_pTail=m_pTail->pLink;
  }
  else
  {
   m_pHead=new QueueFrame(sym);
   m_pTail=m_pHead;
  }
 }
 char Get()
 {
  char res=m_pHead->data;
  QueueFrame * p= m_pHead;
  m_pHead=m_pHead->pLink;
  delete p;
  return res;
 }

Re: Класс Queue

Добавлено: 11 мар 2010, 18:41
Albor
Dragon писал(а):за исключением того, что нужно создать доп. конструктор с одним параметром.
Разве оно того не стоит? :) У тебя в функции Add 18 строк, а у меня 10 , нет заполнения полей вновь созданной структуры и вызова функии empty(), кстати зачем?. В каком варианте код понятнее? :)

Re: Класс Queue

Добавлено: 11 мар 2010, 18:45
Dragon
Честно... твой вариант лучше, проще и наверное быстрее работает (правда у меня очередная пакость вылезла, но с этим разберемся) :) ))

Ну ничего, с опытом прийдет.