Мне нужно сделать предположение здесь: queue
- это ссылка на указатель на головной узел связанного списка. Это кажется разумным предположением из-за того, как оно используется в случае if(queue->next == NULL)
.
Следующий код перезапишет указатель на головной узел, а затем и на любой другой узел, пропуская его.
while(queue->next && queue->next->key < priority) {
queue = queue->next; // bam! previous node leaked back at the caller
}
Вы можете использовать копию головного узла, но ... Есть намного лучшие способы справиться с этим.
Моя рекомендация - не передавать указатель на корневой узел. Передать указатель на указатель на него. Это обрабатывает случай головы, делая голову похожей на любой другой узел и устраняя большую часть кода. Поскольку мы всегда сохраняем указатель на next
предыдущего узла, у нас есть легкий доступ к точке вставки для нового узла и следующего узла.
Вы не можете сделать этот трюк со ссылкой, потому что ссылка не может быть переназначена.
Пример:
#include <string>
#include <iostream>
// my best guess at what pq looks like
struct pq
{
pq* next;
std::string text;
float key;
};
void insert(pq ** queue, // cannot reseat ref, so pointer required
const std::string &text, // ref eliminates copy.
// const because we don't want to change
float priority) {
while((*queue) && // search while more queues
(*queue)->key < priority) // and priority is low
{
queue = &(*queue)->next;
}
*queue = new pq{*queue, // if queue is null, end of list, if not inserted in middle
text,
priority};
}
// Demo
int main()
{
pq * queue = NULL;
insert(&queue, "c", 5);
insert(&queue, "a", 1);
insert(&queue, "b", 2.5);
insert(&queue, "e", 10);
insert(&queue, "d", 7.5);
// print and clean-up.
while (queue)
{
std::cout << queue->text << std::endl;
pq * temp = queue; // temp so we don't lose queue
queue = queue->next;
delete temp; // release node
}
}