Существует ли стандартная реализация Циркулярного списка для С++?
Я хочу использовать круговой список.
За исключением реализации моего собственного ( как этот человек сделал), каковы мои варианты?
В частности, что я хочу сделать, это перебрать список объектов. Когда мой итератор достигнет конца списка, он должен автоматически вернуться к началу. (Да, я понимаю, это может быть опасно.)
См. определение w circular_iterator
во Владивостоке: "Циркулярщик никогда не будет равен CircularList:: end(), поэтому вы всегда можете разыменовать этот итератор.
Ответы
Ответ 1
Нет стандартного кругового списка.
Однако в Boost есть круговой буфер, который может быть полезен.
Если вам ничего не нужно, вы можете просто использовать vector
и получить доступ к элементам с индексом. Вы можете просто mod
указать свой индекс с размером вектора, чтобы добиться того же, что и круговой список.
Ответ 2
Если вы хотите, чтобы что-то похожее на итератор, вы можете катиться самостоятельно, выглядя что-то вроде
template <class baseIter>
class circularIterator {
private:
baseIter cur;
baseIter begin;
baseIter end;
public:
circularIterator(baseIter b, baseIter e, baseIter c=b)
:cur(i), begin(b), end(e) {}
baseIter & operator ++(void) {++cur; if(cur == end) {cur = begin;}}
};
(Другие операции итератора оставлены как упражнение для читателя).
Ответ 3
list<int>::iterator circularNext(list<int> &l, list<int>::iterator &it)
{
return std::next(it) == l.end() ? l.begin() : std::next(it);
}
Ответ 4
В дополнение к ответам, сфокусированным на итераторах @captain-segfault и @mahmoud-khaled, вы также можете использовать std::list
в качестве циклического списка, изменяя то, что вы делаете для извлечения элементов из него. Используйте сращивание, чтобы переместить один конец списка на другой конец по мере его обработки.
template <typename T>
T & circularFront(std::list<T> & l)
{
l.splice(l.end(), l, l.begin());
return l.back();
}
template <typename T>
T & circularBack(std::list<T> & l)
{
l.splice(l.begin(), l, l.rbegin());
return l.front();
}