Страница 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
Честно... твой вариант лучше, проще и наверное быстрее работает (правда у меня очередная пакость вылезла, но с этим разберемся)

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