www.wikidata.de-de.nina.az
Der Hase Igel Algorithmus ist ein Verfahren mit dem in einer einfach verketteten Liste Schleifen mit der Zeitkomplexitat O n displaystyle O n und einer Platzkomplexitat von O 1 displaystyle O 1 gefunden werden konnen Mathematisch betrachtet dient der Algorithmus zum Auffinden von Zyklen in Folgen Er ist auch unter dem Namen Floyds Algorithmus zum Auffinden von Schleifen englisch Floyd s cycle finding algorithm bekannt und darf nicht mit Floyds Algorithmus aus der Graphentheorie verwechselt werden Inhaltsverzeichnis 1 Bedeutung in der Mathematik 2 Prinzip 3 Begrundung 4 Performance Betrachtung 5 Implementierungen 5 1 C 5 2 Ada 5 3 Scheme 6 Vergleich mit anderen Ansatzen zur Schleifenerkennung 6 1 Jeden Knoten merken 6 2 Doppelte Verkettung nutzen 6 3 Jeden Knoten markieren 6 4 Vergleich mit Startelement 7 Bestimmung der Lange und des Einstiegselements 8 WeblinksBedeutung in der Mathematik BearbeitenNeben der trivial ersichtlichen Verwendung zum Auffinden von Schleifen in zur Ablage von Daten genutzten Listen ist der Hase Igel Algorithmus die Grundlage der Pollard Rho Methode zur Bestimmung der Periodenlange einer Zahlenfolge einschliesslich der darauf zuruckfuhrbaren Primfaktorzerlegung Der Algorithmus wird auch im Themenfeld der pseudozufalligen Folgen eingesetzt Prinzip BearbeitenDer Algorithmus besteht aus dem gleichzeitigen Durchlauf der Liste mit unterschiedlichen Schrittweiten Dabei werden zwei Zeiger auf Listenelemente benutzt von denen der eine Igel bei jeder Iteration auf das nachste Element verschoben wird wahrend der andere Hase bei derselben Iteration auf das ubernachste Element verschoben wird Wenn die beiden Zeiger sich begegnen also dasselbe Element referenzieren hat die Liste eine Schleife Wenn einer der beiden Zeiger das Ende der Liste erreicht hat sie keine Schleife Begrundung Bearbeiten nbsp Hase Igel AlgorithmusAm besten kann die Vorgehensweise visualisiert werden indem in einem gezeichneten Diagramm der Weg der beiden Zeiger verfolgt wird Es ist leicht ersichtlich dass sowohl bei einer Schleife mit ungerader Anzahl von Elementen als auch bei einer Schleife mit gerader Anzahl der Hase in hochstens einem Durchlauf des Igels auf diesen trifft Weil mit jedem Schritt des Igels der Hase einen Schritt naher an den Igel herankommt terminiert der Algorithmus in endlicher Zeit Performance Betrachtung BearbeitenIm besten Fall best case performance sind bei einer zyklischen Liste mit m n displaystyle m n nbsp Elementen mit n displaystyle n nbsp als Lange des Zyklus und m displaystyle m nbsp als Anzahl der Elemente vor dem Beginn des Zyklus m displaystyle m nbsp Schritte notwendig da der Igel mindestens den Anfang des Zyklus erreichen muss bevor der Hase ihn auf einer zweiten Runde einholen kann Im schlechtesten Fall worst case performance sind m n displaystyle m n nbsp Schritte notwendig das heisst der Hase erreicht den Igel erst auf dem letzten Element der Liste Zu diesem Zeitpunkt hat der Igel die Schleife genau einmal durchlaufen der Hase jedoch zweimal Implementierungen BearbeitenC Bearbeiten include lt stdio h gt include lt stdlib h gt int main struct liste struct liste next root el hase igel int i Liste erzeugen root el malloc sizeof struct liste for i 0 i lt 5 i struct liste eneu malloc sizeof struct liste el gt next eneu el eneu Zyklischen Verweis vom letzten auf das zweite Element anlegen el gt next root gt next Hase Igel Algorithmus igel root hase root gt next while hase amp amp hase igel printf p p n hase igel igel igel gt next hase hase gt next if hase hase hase gt next if hase puts Zyklus gefunden else puts Liste ist nicht zyklisch return 0 Ada Bearbeiten with Ada Text IO use Ada Text IO procedure Hase Igel is package Int IO is new Integer IO Integer use Int IO type Liste type Liste P is access Liste type Liste is record Name Integer Next Liste P end record Root Last Hase Igel Liste P begin Liste erzeugen Root new Liste Name gt 0 Next gt null Last Root for I in 1 12 loop Last Next new Liste Name gt I Next gt null Last Last Next end loop zyklischen Verweis erzeugen Last Next Root Next Next Hase Igel Algorithmus Igel Root Hase Igel Next while Hase null and Hase Igel loop Put Hase Name 4 Put Igel Name 4 New Line Igel Igel Next Hase Hase Next exit when Hase null Hase Hase Next end loop if Hase null then Put Line Liste ist nicht zyklisch else Put Line Zyklus gefunden end if end Hase Igel Scheme Bearbeiten define is mlist lst define iter hase igel counter hase und igel sind meine zeiger cond null hase t ist a null gt t eq mcar hase mcar igel f else if counter 1 setze counter auf startwert 1 iter mcdr hase mcdr igel 0 iter mcdr hase igel 1 igel startet bei plus 1 iter mcdr lst lst 0 define a mlist 2 3 5 7 prufbeispiel is mlist a Vergleich mit anderen Ansatzen zur Schleifenerkennung BearbeitenJeden Knoten merken Bearbeiten AnsatzJeder durchlaufene Knoten wird in einer geeigneten Struktur gespeichert Probleme Das Verfahren benotigt sehr viel Speicherplatz und Rechenleistung und ist daher ungeeignet fur grosse Listen Doppelte Verkettung nutzen Bearbeiten AnsatzIn einer doppelt verketteten Liste hat jedes Element sowohl einen Zeiger auf das folgende als auch auf das vorhergehende Element Beim Durchlauf einer solchen Liste muss also jedes Element das vorher besuchte als vorhergehendes Element referenzieren Wenn das nicht so ist muss die Liste eine Schleife haben da Korrektheit der Verkettung vorausgesetzt zu diesem besuchten Element zwei Zeiger existieren Probleme Das Verfahren funktioniert nur wenn die doppelte Verkettung nicht fehlerhaft ist Eine Schleife uber die ganze Liste muss gesondert am Zeiger auf das vorhergehende Element des Startelements gepruft werden Jeden Knoten markieren Bearbeiten AnsatzDie Liste wird durchlaufen dabei wird jeder Knoten markiert Wenn ein markierter Knoten getroffen wird hat die Liste eine Schleife Probleme Das Verfahren funktioniert nicht da vor dem Durchsuchen der Liste diese zunachst einmal durchlaufen werden muss um alle Markierungen initial auf nicht besucht zu setzen Dies ist aber im Fall einer Schleife nicht zuverlassig moglich Die Markierung benotigt zusatzlichen Speicherbedarf Vergleich mit Startelement Bearbeiten AnsatzDer Zeiger auf das nachste Element jedes Listenelements wird mit dem Startelement verglichen Wenn ein Element auf das Startelement zeigt hat die Liste eine Schleife Probleme Das Verfahren funktioniert nur bei Listen die eine einzige Schleife sind Listen die an irgendeiner Position nach dem Startelement eine Schleife haben werden nicht erkannt Bestimmung der Lange und des Einstiegselements BearbeitenHat man eine Schleife gefunden so kann man mit ahnlichen Verfahren deren Lange sowie das Einstiegselement in die Schleife bestimmen Die Bestimmung der Lange ist trivial Man nimmt den Hasen aus dem Rennen und lasst den Igel weiterlaufen bis er wieder den Treffpunkt erreicht Die Zahl seiner dabei gemachten Schritte ist die Lange der Schleife Die Bestimmung des Einstiegselements kann erfolgen indem man einen zweiten Igel an den Start bringt Der erste Igel startet wieder vom Treffpunkt aus Beide Igel machen nun jeweils einen Schritt bis sie sich treffen Dieser Treffpunkt der im Allgemeinen nicht mit dem Treffpunkt von Hase und Igel identisch ist ist das Einstiegselement in die Schleife und wird erreicht nachdem beide Igel jeweils m displaystyle m nbsp Schritte gemacht haben Der Beweis dieser Tatsache macht davon Gebrauch dass die Anzahl der Schritte vom Start bis zum Treffpunkt von Hase und Igel ein Vielfaches der Lange der Schleife ist Ein einsichtigeres Verfahren welches allerdings m n displaystyle m n nbsp Schritte benotigt bringt beide Igel an den Start und gibt dann dem ersten Igel n displaystyle n nbsp Schritte Vorsprung bevor wieder beide Igel sich nach jeweils m displaystyle m nbsp Schritten beim Einstiegselement treffen Weblinks BearbeitenFinding a Loop in a Singly Linked List englisch Abgerufen von https de wikipedia org w index php title Hase Igel Algorithmus amp oldid 224560289