Ich möchte eine kreisförmige Liste verwenden.
Kurz vor der Implementierung meiner eigenen (wie diese Person) Welche Möglichkeiten habe ich?
Insbesondere möchte ich eine Liste von Objekten durchlaufen. Wenn mein Iterator das Ende der Liste erreicht, sollte er automatisch zum Anfang zurückkehren. (Ja, mir ist klar, dass dies gefährlich sein könnte.)
Siehe Vladimirs Definition von a circular_iterator
: “Ein kreisförmiger_Iterator wird niemals mit CircularList::end() gleich sein, daher können Sie diesen Iterator immer dereferenzieren.”
Es gibt keine Standard-Rundschreibenliste.
Allerdings gibt es eine kreisförmiger Puffer in Boost, was hilfreich sein könnte.
Wenn Sie nichts Besonderes brauchen, können Sie in Betracht ziehen, einfach a zu verwenden vector
und Zugreifen auf die Elemente mit einem Index. Du kannst einfach mod
Ihr Index mit der Größe des Vektors, um ungefähr dasselbe zu erreichen wie eine kreisförmige Liste.
Wenn Sie möchten, dass etwas wie ein Iterator aussieht, können Sie Ihren eigenen rollen, der so ähnlich aussieht
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;}}
};
(Andere Iteratoroperationen werden dem Leser als Übung überlassen).
list<int>::iterator circularNext(list<int> &l, list<int>::iterator &it)
{
return std::next(it) == l.end() ? l.begin() : std::next(it);
}
Zusätzlich zu den iteratororientierten Antworten von @captain-segfault und @mahmoud-khaled können Sie auch verwenden std::list
als kreisförmige Liste, indem Sie ändern, was Sie tun, um Elemente daraus abzurufen. Benutzen spleißen um ein Ende der Liste während der Verarbeitung an das andere Ende zu verschieben.
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();
}
Ich habe diese Lösung gefunden. Funktioniert gut für mich.
std::list<int> List{ 1,2,3,4,5,6 };
auto it = List.end();
it--;
it._Ptr->_Next = List.begin()._Ptr; // Next Node of the last elemen is now first elemen of the List
List.begin()._Ptr->_Prev = it._Ptr; // Prev Node of the first element is now Last node
for (int num : List)
{
std::cout << num << 'n';
}
In diesem Fall machen wir eine Endlosschleife. Sollte auch rückwärts funktionieren.
Ausgabe
1
2
3
4
5
6
1
2
3
4
5
6
1
.
.
.
5735800cookie-checkGibt es eine Standardimplementierung einer Circular List für C++?yes