I am studying old exams for an exam. One task is to implement an insert and print function that inserts elements at the beginning of a circular list. A program is provided to test the students solution.
My solution for the insert is:
void Circular_List::insert(std::string const& str)
{
if (entry == nullptr) {
entry = new Element(str);
entry -> next = entry;
}
else {
Element* temp = entry;
entry = new Element(str);
entry -> next = temp;
}
}
It seems to work because my print:
void Circular_List::print() const
{
Element* temp = entry;
while (temp -> next != temp) {
cout << temp -> name << endl;
temp = temp -> next;
}
}
prints the list in the right order EXCEPT for the element that I first added. I don't understand why it doesn't print the first element. The program provided prints out 20 iterations. For example if I insert a,b,c,d,e the program will print
d->c->b->a->a->a->a->a->a->a->a->a->a->a->a->a->a->a->a->a->
This seems very off, should it not loop to the front of the list instead of just printing a?
The test program:
int j = 0;
for (Circular_List::Iterator i = l.begin(); i != l.end() && j < 20; ++i, ++j)
{
cout << *i << "->";
}
cout << endl;
class Iterator
{
public:
Iterator(Element* e) : pos(e) {}
~Iterator() = default;
Iterator(Iterator const&) = default;
Iterator& operator=(Iterator const&) = default;
bool operator!=(Iterator const& i) { return pos != i.pos; }
operator bool() { return pos != nullptr; }
Iterator& operator++() { pos = pos->next; return *this;}
std::string operator*() { return pos->name; }
private:
Element* pos;
};
I assume my insert is wrong but I can't figure out what I'm doing wrong?
When you are inserting the second element to the list, your first element keeps next entry pointing back to itself. You need to update two next fields: one in inserted record and another in the list to point back to inserted record. You fail to do the latter. The else clause should LIKELY be:
Element* temp = new Element(str);
temp->next = entry->next;
entry->next = temp;
entry = temp;
This makes entry a pointer to LAST cycle element and entry->next - the first cycle element;
BTW, your second drawing is incorrect as 'a'->next should be pointing back to 'a' and not to entry.