Gibt es eine Standardimplementierung einer Circular List für C++?

Lesezeit: 3 Minuten

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.

  • Danke Naff! Den Index mit der Größe des Vektors zu modifizieren ist eine so einfache Lösung, dass es mir peinlich ist, dass ich nicht daran gedacht habe.

    – Runcibel

    3. Juni 09 um 22:13 Uhr

  • Wenn Sie sicherstellen, dass die Größe Ihrer vector eine Zweierpotenz ist, verwenden Sie dann anstelle des teuren Overheads der Modulo-Operation die bitweise & Betreiber statt, da es nur einen Zyklus kostet. Es funktioniert so: (n mod (2^k)) == (n & (2^k - 1)) z.B n % 256 == (n & (255))

    – Benjamin R

    20. März 17 um 6:27 Uhr


  • Der Compiler ersetzt mod ohnehin durch Bitoperationen, wo es für Sie angebracht ist, ohne dass Code verschleiert werden muss, es sei denn, Sie benötigen wirklich die nicht optimierte Debug-Leistung

    – GeckoGeorge

    23. Dezember 2020 um 9:31 Uhr

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
.
.

  • Hallo Doctor smail, hier geht es nicht darum, eine verkettete Liste kreisförmig zu machen, Runcible sucht eine Klasse auflisten das ist kreisförmig.

    – Leckereien

    20. August 21 um 23:52 Uhr

  • Hallo Doctor smail, hier geht es nicht darum, eine verkettete Liste kreisförmig zu machen, Runcible sucht eine Klasse auflisten das ist kreisförmig.

    – Leckereien

    20. August 21 um 23:52 Uhr

.

573580cookie-checkGibt es eine Standardimplementierung einer Circular List für C++?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy