Ich kann den Vorteil der Verwendung von zwei Stapeln sehen, wenn eine Array-Implementierung verwendet wird, da Stacks einfacher mit Arrays als Warteschlangen implementiert werden. Aber wenn Linked-Listen verwendet werden, was ist der Vorteil? Das Aufrufen des Stapels in die Warteschlange erhöht den Aufwand für Implementierungen mit verknüpften Listen und Arrays.Warum zwei Stapel verwenden, um eine Warteschlange zu erstellen?
Antwort
Es ist ein verbreiteter Weg, um eine Warteschlange in funktionalen Programmiersprachen mit rein funktionalen (unveränderlich, sondern teile Struktur) Listen (zB Clojure, Haskell, Erlang ...) zu implementieren:
- verwenden, um ein Paar von Listen um eine Warteschlange darzustellen, in der Elemente in FIFO-Reihenfolge in der ersten Liste und in LIFO-Reihenfolge in der zweiten Liste
- Warteschlange in Warteschlange durch Voranstellen an die zweite Liste
- Warteschlange aus der Warteschlange durch das erste Element des ersten Warteschlange Liste
- wenn die erste Liste ist leer: die zweite umzukehren und die erste Liste mit sich, ersetzen und die zweite Liste mit einer leeren Liste
(alle Operationen des neuen Warteschlangenobjekt zusätzlich zu allen möglichen Rückgabewerte zurück)
ersetzenDer Punkt ist, dass das Hinzufügen (Entfernen) eines Elements zu (von) der Vorderseite einer rein funktionalen Liste O (1) ist und die umgekehrte Operation, die O (n) ist, wird über alle Dequeues amortisiert, so dass es nahe O (1), wodurch Sie eine ~ O (1) Warteschlangenimplementierung mit unveränderlichen Datenstrukturen erhalten.
der zweite Schritt, ich glaube, das letzte Wort sollte 'list' statt' queue' sein, um es so zu machen, "Warteschlange in die Warteschlange durch Voranstellen an die zweite Liste". –
Vielen Dank @LihangLi, behoben! – liwp
Es ist eine gute Lernerfahrung, aber keine praktische.
Sie können eine unveränderbare Warteschlange mit zwei unveränderlichen Stapeln erstellen.
Wenn Sie jedoch nur eine veränderbare Warteschlange möchten, ist die Verwendung von zwei Stapeln eine gute Methode, um sie langsamer und komplizierter zu machen, als nur eine verknüpfte Liste zu verwenden.
Dieser Ansatz kann verwendet werden, um eine lock-free-Warteschlange unter Verwendung von zwei atomaren Single-Linked-List-basierten Stapeln zu erstellen, wie sie von Win32 bereitgestellt werden: Interlocked Singly Linked Lists. Der Algorithmus könnte wie in liwp's answer beschrieben sein, obwohl der Umpackschritt (Punkt 4) ein wenig optimiert werden kann.
Lock-free Datenstrukturen und Algorithmen ist eine sehr spannende (zu einigen von uns) Bereich der Programmierung, aber sie müssen sehr sorgfältig verwendet werden. In einer allgemeinen Situation sind lockbasierte Algorithmen effizienter.
In einem Multi-Writer-Einzel-Leser-Fall, ist es einfach zu Enqueue-Operationen in effizienter Lock-free-Mode, und auch für die Ausstieg (nicht zu sperren Autoren und Annahme eines einzigen Reader) wenn man die Dequeue mit einer "pop all" -Operation im Posteingang startet (im Grunde ein "Interlocked.Exchange"). Wenn es mehrere Reader geben könnte, ist es wahrscheinlich am besten, sie locking zu verwenden, um untereinander zu arbitrieren Ich glaube nicht, dass das die Autoren betrifft) – supercat
Dies ist die Erklärung, nach der ich hier gesucht habe. –
- 1. Eine zirkuläre Warteschlange durchlaufen, ohne eine temporäre Warteschlange zu verwenden
- 2. Warum Umbruch ist für Warteschlange erforderlich, aber nicht für Stapel?
- 3. So erstellen Sie asynchrone Methoden, die eine Warteschlange threadsicher verwenden
- 4. Hauptgründe, warum Programmiersprachen-Laufzeiten Stapel verwenden?
- 5. jQuery-Ereigniskette - vom Stapel zur Warteschlange
- 6. Kartenfelder aus zwei Tabellen, um eine einzige Entität zu erstellen
- 7. Warum App.config verwenden, um Konfigurationsdaten zu speichern?
- 8. Ist es möglich, eine Warteschlange für HashMap-Set zu erstellen?
- 9. Warum zwei Typen (Grenzen/Rahmen) verwenden, um eine Ansicht statt einer zu beschreiben?
- 10. C# -Website erstellen, um Webservice zu verwenden
- 11. Verwenden Sie nant, um eine benutzerdefinierte nant Aufgabe zu erstellen
- 12. Verwenden Sie Zend Framework, um eine flexible Basisanwendung zu erstellen
- 13. Können wir Fragmente verwenden, um eine Registrierungsseite zu erstellen
- 14. Spring: Builder-Muster verwenden, um eine Bean zu erstellen
- 15. AJAX verwenden, um einen Datenlogger zu erstellen
- 16. Listenverstehen verwenden, um ein Tupel zu erstellen
- 17. Der effizienteste Weg, um eine Warteschlange zu überwachen
- 18. Best Practice zu verwenden Scala unveränderlich Warteschlange
- 19. Warum c() verwenden, um Vektor zu definieren?
- 20. Wann Warteschlange über Arraylist zu verwenden ist
- 21. Zwei Möglichkeiten, um Python-basierte Webseiten zu erstellen?
- 22. Was zu verwenden, um zwei. NET-Programme Informationen zu übertragen
- 23. Erstellen einer URL-Warteschlange
- 24. MongoDB-Array als Stapel verwenden
- 25. xcode kompilieren Flags, um zwei Apps zu erstellen
- 26. Erstellen einer AWS SQS-Warteschlange
- 27. einen Konstruktor Verwenden Sie einen Stapel
- 28. Stapel und Queue-Enumeration, um
- 29. Regex verwenden, um eine Telefonnummer zu bestätigen?
- 30. Erstellen einer kleinen Warteschlange (Generics)
Wer verwendet zwei Stapel, um eine Warteschlange zu erstellen? Ich verstehe die Situation nicht wirklich (sorry :( – helios