Rekursiver Algorithmus: Beschreibung, Analyse, Merkmale und Beispiele

Inhaltsverzeichnis:

Rekursiver Algorithmus: Beschreibung, Analyse, Merkmale und Beispiele
Rekursiver Algorithmus: Beschreibung, Analyse, Merkmale und Beispiele
Anonim

Modernes Verständnis von Rekursion: Definition von Funktionalität und Zugriff darauf von außen und von dieser Funktionalität. Es wird angenommen, dass die Rekursion von Mathematikern geboren wurde: Fakultätsrechnung, unendliche Reihen, Fraktale, fortgesetzte Brüche … Rekursion ist jedoch überall zu finden. Objektive Naturgesetze „betrachten“die Rekursion als ihren Hauptalgorithmus und ihre Ausdrucksform (Existenz) nicht so sehr der Objekte der materiellen Welt, sondern im Allgemeinen als Hauptalgorithmus der Bewegung.

rekursiver Algorithmus
rekursiver Algorithmus

Menschen verschiedener Fachrichtungen in verschiedenen Wissenschafts- und Technologiebereichen verwenden den rekursiven Algorithmus f (x), wobei "x ~/=f (x)". Eine Funktion, die sich selbst aufruft, ist eine starke Lösung, aber das Bilden und Verstehen dieser Lösung ist in den meisten Fällen eine sehr schwierige Aufgabe.

In der Antike wurde Rekursion verwendet, um den Palastraum zu vergrößern. Durch ein System von aufeinander gerichteten Spiegeln können Sie verblüffende dreidimensionale Raumeffekte erzeugen. Aber ist es so einfach zu verstehen, wiediese Spiegel einstellen? Noch schwieriger ist es zu bestimmen, wo sich ein Punkt im Raum befindet, der durch mehrere Spiegel reflektiert wird.

Rekursion, rekursive Algorithmen: Bedeutung und Syntax

Das Problem, das durch Wiederholung einer Folge von Operationen formuliert wird, kann rekursiv gelöst werden. Ein einfacher Algorithmus (Berechnung einer quadratischen Gleichung, ein Skript zum Füllen einer Webseite mit Informationen, Lesen einer Datei, Senden einer Nachricht…) erfordert keine Rekursion.

Hauptunterschiede des Algorithmus, der eine rekursive Lösung erlaubt:

  • es gibt einen Algorithmus, der mehrmals ausgeführt werden muss;
  • Algorithmus benötigt Daten, die sich jedes Mal ändern;
  • der Algorithmus muss sich nicht jedes Mal ändern;
  • es gibt eine letzte Bedingung: der Algorithmus ist rekursiv - nicht unendlich.

Im Allgemeinen kann nicht argumentiert werden, dass die einmalige Ausführung eine notwendige Bedingung für das Fehlen eines Rekursionsgrundes ist. Sie können auch keine obligatorische Endbedingung verlangen: unendliche Rekursionen haben ihren eigenen Geltungsbereich.

Der Algorithmus ist rekursiv: wenn eine Abfolge von Operationen wiederholt ausgeführt wird, auf Daten, die sich jedes Mal ändern und jedes Mal ein neues Ergebnis liefern.

Rekursionsformel

Das mathematische Verständnis der Rekursion und ihr Analogon in der Programmierung sind unterschiedlich. Mathematik, obwohl es Anzeichen für Programmierung gibt, aber Programmierung ist Mathematik von viel höherer Ordnung.

rekursiver Algorithmus f
rekursiver Algorithmus f

Ein gut geschriebener Algorithmus ist wie ein Spiegel des Intellekts seines Autors. AllgemeinDie Rekursionsformel in der Programmierung lautet „f(x)“, wobei „x ~/=f(x)“mindestens zwei Interpretationen hat. Dabei ist „~“die Ähnlichkeit oder Abwesenheit des Ergebnisses und „=“das Vorhandensein des Ergebnisses der Funktion.

Erste Option: Datendynamik.

  • Funktion "f(x)" hat einen rekursiven und unveränderlichen Algorithmus;
  • "x" und das Ergebnis "f(x)" haben jedes Mal neue Werte, das Ergebnis "f(x)" ist der neue "x"-Parameter dieser Funktion.

Zweite Option: Code-Dynamik.

  • Funktion "f(x)" hat mehrere Algorithmen, die die Daten verfeinern (analysieren);
  • Datenanalyse - ein Teil des Codes und die Implementierung rekursiver Algorithmen, die die gewünschte Aktion ausführen - der zweite Teil des Codes;
  • das Ergebnis der Funktion "f(x)" ist nicht.

Kein Ergebnis ist normal. Programmieren ist keine Mathematik, hier muss das Ergebnis nicht explizit vorhanden sein. Eine rekursive Funktion kann Websites einfach parsen und die Datenbank füllen oder Objekte entsprechend der eingehenden Eingabe instanziieren.

Daten und Rekursion

Bei der Programmierung rekursiver Algorithmen geht es nicht darum, eine Fakultät zu berechnen, bei der die Funktion jedes Mal einen gegebenen Wert erhält, der um eins mehr oder weniger als eins ist - die Implementierungsoption hängt von den Vorlieben des Entwicklers ab.

Egal wie die Fakultät "8!",Algorithmus, der strikt dieser Formel folgt.

Informationsverarbeitung ist "Mathematik" ganz anderer Ordnung. Rekursive Funktionen und Algorithmen arbeiten hier an Buchstaben, Wörtern, Phrasen, Sätzen und Absätzen. Jede nächste Ebene verwendet die vorherige.

Der Eingangsdatenstrom wird über einen weiten Bereich von Bedingungen analysiert, aber der Analyseprozess ist im Allgemeinen rekursiv. Es macht keinen Sinn, eindeutige Algorithmen für alle Varianten des Eingabestroms zu schreiben. Es sollte eine Funktionalität geben. Rekursive Algorithmen sind hier Beispiele dafür, wie ein zur Eingabe adäquater Ausgabestrom gebildet werden kann. Dies ist nicht das Ergebnis des rekursiven Algorithmus, aber es ist die gewünschte und notwendige Lösung.

Abstraktion, Rekursion und OOP

Objektorientierte Programmierung (OOP) und Rekursion sind grundlegend unterschiedliche Entitäten, aber sie ergänzen sich perfekt. Abstraktion hat nichts mit Rekursion zu tun, aber durch die Linse von OOP schafft sie die Möglichkeit, kontextuelle Rekursion zu implementieren.

Beispielsweise werden Informationen geparst und Buchstaben, Wörter, Phrasen, Sätze und Absätze separat hervorgehoben. Offensichtlich wird der Entwickler für die Erstellung von Instanzen von Objekten dieser fünf Typen sorgen und eine Lösung rekursiver Algorithmen auf jeder Ebene anbieten.

Programmierung rekursiver Algorithmen
Programmierung rekursiver Algorithmen

Indessen, wenn auf der Ebene der Buchstaben „es keinen Sinn macht, nach Bedeutung zu suchen“, dann erscheint die Semantik auf der Ebene der Wörter. Sie können Wörter in Verben, Substantive, Adverbien, Präpositionen usw. unterteilen. Sie können noch weiter gehen und Fälle definieren.

Auf Phrasenebene wird die Semantik durch Satzzeichen und Logik ergänztWortkombinationen. Auf der Ebene der Sätze findet sich eine perfektere semantische Ebene, und ein Absatz kann als vollständiger Gedanke betrachtet werden.

Objektorientierte Entwicklung legt die Vererbung von Eigenschaften und Methoden fest und schlägt vor, die Hierarchie von Objekten mit der Schaffung eines vollständig abstrakten Vorfahren zu beginnen. Gleichzeitig wird die Analyse jedes Nachkommen zweifellos rekursiv sein und sich auf technischer Ebene in vielen Positionen (Buchstaben, Wörter, Phrasen und Sätze) nicht zu sehr unterscheiden. Absätze mögen wie ganze Gedanken aus dieser Liste hervorstechen, aber sie sind nicht das Wesentliche.

Es ist wichtig, dass der überwiegende Teil des Algorithmus auf der abstrakten Vorfahrenebene formuliert werden kann, indem er auf der Ebene jedes Nachkommens mit Daten und Methoden verfeinert wird, die von der abstrakten Ebene aufgerufen werden. In diesem Zusammenhang eröffnet die Abstraktion neue Horizonte für die Rekursion.

Historische Merkmale von OOP

OOP ist zweimal in die Welt der Software gekommen, obwohl einige Experten das Aufkommen von Cloud Computing und modernen Ideen über Objekte und Klassen als eine neue Runde in der Entwicklung von IT-Technologien herausstellen mögen.

Die Begriffe „Objekt“und „Objektiv“werden im modernen OOP-Kontext üblicherweise den 50er und 60er Jahren des letzten Jahrhunderts zugeschrieben, aber sie werden mit 1965 und der Entstehung von Simula, Lisp, Algol, Smalltalk in Verbindung gebracht.

Programmierung war damals noch nicht besonders entwickelt und konnte auf revolutionäre Konzepte nicht angemessen reagieren. Der Kampf der Ideen und Programmierstile (C/C++ und Pascal – meistens) war noch weit entfernt, und Datenbanken wurden noch konzeptionell geformt.

Rekursion rekursive Algorithmen
Rekursion rekursive Algorithmen

In den späten 80er und frühen 90er Jahren tauchten Objekte in Pascal auf und jeder erinnerte sich an Klassen in C / C ++ - dies markierte eine neue Runde des Interesses an OOP und damals wurden Tools, hauptsächlich Programmiersprachen, nicht mehr unterstützen nur objektorientierte Ideen, entwickeln sich aber entsprechend weiter.

Wenn frühere rekursive Algorithmen nur Funktionen waren, die im allgemeinen Code des Programms verwendet wurden, könnte die Rekursion jetzt Teil der Eigenschaften eines Objekts (einer Klasse) werden, was interessante Möglichkeiten im Zusammenhang mit der Vererbung bietet.

Funktion des modernen OOP

Die Entwicklung von OOP deklarierte ursprünglich Objekte (Klassen) als Sammlungen von Daten und Eigenschaften (Methoden). Tatsächlich ging es um Daten, die Syntax und Bedeutung haben. Aber dann war es nicht möglich, OOP als Werkzeug zur Verw altung realer Objekte zu präsentieren.

rekursive Funktionen und Algorithmen
rekursive Funktionen und Algorithmen

OOP ist zu einem Werkzeug geworden, um "Computernatur"-Objekte zu verw alten. Ein Skript, eine Sch altfläche, ein Menüpunkt, eine Menüleiste, ein Tag in einem Browserfenster ist ein Objekt. Aber keine Maschine, kein Lebensmittel, kein Wort, kein Satz. Reale Objekte sind außerhalb der objektorientierten Programmierung geblieben, und Computerwerkzeuge haben eine neue Inkarnation angenommen.

Aufgrund der Unterschiede in gängigen Programmiersprachen sind viele OOP-Dialekte entstanden. Semantisch sind sie praktisch gleichwertig, und ihr Fokus auf die instrumentelle Sphäre und nicht auf die angewandte ermöglicht es, die Beschreibung realer Objekte darüber hinaus zu führenAlgorithmen und stellen deren plattform- und sprachübergreifende "Existenz" sicher.

Stacks und Funktionsaufrufmechanismen

Mechanismen zum Aufrufen von Funktionen (Prozeduren, Algorithmen) erfordern das Übergeben von Daten (Parametern), das Zurückgeben eines Ergebnisses und das Merken der Adresse des Operators, der die Kontrolle erh alten muss, nachdem die Funktion (Prozedur) abgeschlossen ist.

Beispiele für rekursive Algorithmen
Beispiele für rekursive Algorithmen

Normalerweise wird dafür der Stack verwendet, wobei Programmiersprachen oder der Entwickler selbst vielfältige Möglichkeiten zur Übergabe der Kontrolle bieten können. Die moderne Programmierung gibt zu, dass der Name einer Funktion nicht nur ein Parameter sein kann: Er kann während der Ausführung des Algorithmus gebildet werden. Ein Algorithmus kann auch erstellt werden, während ein anderer Algorithmus ausgeführt wird.

Das Konzept der rekursiven Algorithmen, bei denen ihre Namen und Körper zum Zeitpunkt der Aufgabenstellung (Auswahl des gewünschten Algorithmus) bestimmt werden können, erweitert die Rekursivität nicht nur darauf, wie etwas zu tun ist, sondern auch, wer genau sollte Tu es. Die Auswahl eines Algorithmus anhand seines „aussagekräftigen“Namens ist vielversprechend, bereitet aber Schwierigkeiten.

Rekursivität auf eine Menge von Funktionen

Man kann nicht sagen, dass ein Algorithmus rekursiv ist, wenn er sich selbst aufruft und das war's. Programmieren ist kein Dogma, und das Konzept der Rekursivität ist keine ausschließliche Voraussetzung, um sich selbst aus dem Körper des eigenen Algorithmus aufzurufen.

Praktische Anwendungen ergeben nicht immer eine saubere Lösung. Oft müssen die Ausgangsdaten aufbereitet und das Ergebnis des rekursiven Aufrufs im Kontext der gesamten Problemstellung (des gesamten Algorithmus) analysiert werdeninsgesamt.

Tatsächlich kann oder sollte nicht nur vor dem Aufruf einer rekursiven Funktion, sondern auch nach deren Beendigung ein anderes Programm aufgerufen werden. Wenn es beim Aufruf keine besonderen Probleme gibt: Die rekursive Funktion A() ruft die Funktion B() auf, die etwas macht und A() aufruft, dann gibt es sofort ein Problem mit der Rückgabe der Kontrolle. Nach Abschluss des rekursiven Aufrufs muss die Funktion A() die Kontrolle erh alten, um B() erneut aufzurufen, wodurch sie erneut aufgerufen wird. Die Kontrolle so zurückzugeben, wie sie auf dem Stack geordnet sein sollte, an B() zurückzugeben, ist die falsche Lösung.

Der Programmierer ist in der Wahl der Parameter nicht eingeschränkt und kann diese mit Funktionsnamen ergänzen. Mit anderen Worten, die ideale Lösung besteht darin, den Namen von B() an A() zu übergeben und A() selbst B() aufrufen zu lassen. In diesem Fall gibt es keine Probleme mit der Rückgabe der Kontrolle und die Implementierung des rekursiven Algorithmus wird transparenter.

Verständnis und Grad der Rekursion

Das Problem bei der Entwicklung rekursiver Algorithmen ist, dass Sie die Dynamik des Prozesses verstehen müssen. Bei der Verwendung von Rekursion in Objektmethoden, insbesondere auf der Ebene eines abstrakten Vorfahren, besteht das Problem, den eigenen Algorithmus im Kontext seiner Ausführungszeit zu verstehen.

rekursive Algorithmen lösen
rekursive Algorithmen lösen

Derzeit gibt es keine Beschränkungen hinsichtlich der Verschachtelungsebene von Funktionen und Stapelkapazität in Aufrufmechanismen, aber es gibt ein Problem des Verständnisses: zu welchem Zeitpunkt welche Datenebene oder welche Stelle im allgemeinen Algorithmus als rekursiv bezeichnet wird Funktion und auf welcher Anzahl von Anrufen sie selbst ist.

Vorhandene Debugging-Tools sind oft machtlossage dem Programmierer die richtige Lösung.

Schleifen und Rekursion

Es wird davon ausgegangen, dass die zyklische Ausführung der Rekursion entspricht. Tatsächlich kann der rekursive Algorithmus in einigen Fällen in der Syntax von bedingten und zyklischen Konstrukten implementiert werden.

Wenn jedoch klar ist, dass eine bestimmte Funktion durch einen rekursiven Algorithmus implementiert werden muss, sollte jegliche externe Verwendung einer Schleife oder bedingter Anweisungen aufgegeben werden.

Implementierung rekursiver Algorithmen
Implementierung rekursiver Algorithmen

Die Bedeutung hier ist, dass eine rekursive Lösung in Form einer Funktion, die sich selbst verwendet, ein vollständiger, funktional vollständiger Algorithmus ist. Dieser Algorithmus erfordert, dass der Programmierer ihn mit Mühe erstellt und die Dynamik des Algorithmus versteht, aber es wird die endgültige Lösung sein, die keine externe Kontrolle erfordert.

Jede Kombination aus externen bedingten und zyklischen Operatoren erlaubt es uns nicht, den rekursiven Algorithmus als vollständige Funktion darzustellen.

Rekursionskonsens und OOP

Bei fast allen Varianten der Entwicklung eines rekursiven Algorithmus entsteht der Plan, zwei Algorithmen zu entwickeln. Der erste Algorithmus generiert eine Liste zukünftiger Objekte (Instanzen) und der zweite Algorithmus ist eigentlich eine rekursive Funktion.

Die beste Lösung wäre, die Rekursion als einzelne Eigenschaft (Methode) anzuordnen, die den rekursiven Algorithmus tatsächlich enthält, und die gesamte Vorarbeit in den Objektkonstruktor zu stecken.

Ein rekursiver Algorithmus ist nur dann die richtige Lösung, wenn er funktioniertallein, ohne fremde Kontrolle und Führung. Ein externer Algorithmus kann nur ein Signal zum Arbeiten geben. Das Ergebnis dieser Arbeit sollte die erwartete Lösung sein, ohne externe Unterstützung.

Rekursion sollte immer eine komplett eigenständige Lösung sein.

Intuitives Verständnis und funktionale Vollständigkeit

Als die objektorientierte Programmierung zum De-facto-Standard wurde, wurde klar, dass man sein eigenes Denken ändern muss, um effektiv zu programmieren. Der Programmierer muss während der Ausführung des Algorithmus von der Syntax und Semantik der Sprache zur Dynamik der Semantik übergehen.

Rekursionseigenschaft: auf alles anwendbar:

  • Web Scraping;
  • Suchoperationen;
  • Parsen von Textinformationen;
  • MS Word-Dokumente lesen oder erstellen;
  • Sampling oder Analysieren von Tags…

Charakteristisch für OOP: Es ermöglicht, einen rekursiven Algorithmus auf der Ebene eines abstrakten Vorfahren zu beschreiben, aber dafür zu sorgen, dass er sich auf eindeutige Nachkommen bezieht, von denen jeder seine eigene Palette von Daten und Eigenschaften hat.

Konzept der rekursiven Algorithmen
Konzept der rekursiven Algorithmen

Rekursion ist ideal, weil sie die funktionale Vollständigkeit ihres Algorithmus erfordert. OOP verbessert die Leistung eines rekursiven Algorithmus, indem es ihm Zugriff auf alle eindeutigen Kinder gibt.

Empfohlen: