Rekursive Programmierung

Bei der rekursiven Programmierung ruft sich eine Prozedur, Funktion oder Methode in einem Computerprogramm selbst wieder auf (d. h. enthält eine Rekursion). Auch der gegenseitige Aufruf stellt eine Rekursion dar.

Wichtig bei der rekursiven Programmierung ist eine Abbruchbedingung in dieser Funktion, weil sich das rekursive Programm sonst theoretisch unendlich oft selbst aufrufen würde.

Rekursive Programmierung kann unter anderem in prozeduralen und objektorientierten Programmiersprachen angewandt werden. Obwohl diese Sprachen in ihrem Sprachstandard die Rekursion ausdrücklich zulassen, stellen Selbstaufrufe und gegenseitige Aufrufe hier (aufgrund der verwendeten Programmierparadigmen) jedoch eher die Ausnahme dar. Auch wenn in der Praxis zur Verbesserung des Programmierstils auch hier durchaus häufig auf Rekursion zurückgegriffen wird, sind die meisten Funktionen in diesen Sprachen doch rein iterativ.

In einigen Sprachen, wie z. B. in manchen funktionalen Programmiersprachen oder Makroprozessoren, muss die rekursive Programmiermethode zwingend verwendet werden, da iterative Sprachkonstrukte fehlen.

Beispiele

Fakultät

Ein Beispiel für die Verwendung einer rekursiven Programmierung ist die Berechnung der Fakultät einer Zahl. Die Fakultät ist das Produkt aller ganzen Zahlen von 1 bis zu dieser Zahl. Die Fakultät von 4 ist also .

Mathematiker definieren die Fakultät meistens so (eine rekursive Definition):

  • Die Fakultät der Zahl 0 ist definitionsgemäß 1.
  • Die Fakultät einer ganzen Zahl, die größer als Null ist, ist das Produkt dieser Zahl mit der Fakultät der nächstkleineren ganzen Zahl.

Die Definition funktioniert so:

  • Will man die Fakultät von 4 berechnen, so muss man zunächst die Fakultät von 3 berechnen und das Ergebnis mit 4 multiplizieren.
  • Will man die Fakultät von 3 berechnen, so muss man zunächst die Fakultät von 2 berechnen und das Ergebnis mit 3 multiplizieren.
  • Will man die Fakultät von 2 berechnen, so muss man zunächst die Fakultät von 1 berechnen und das Ergebnis mit 2 multiplizieren.
  • Will man die Fakultät von 1 berechnen, so muss man zunächst die Fakultät von 0 berechnen und das Ergebnis mit 1 multiplizieren.
  • Die Fakultät von 0 ist nach Definition 1.
  • Die Fakultät von 1 ist also 1*1=1
  • Die Fakultät von 2 ist also 1*1*2=2
  • Die Fakultät von 3 ist also 1*1*2*3=6
  • Die Fakultät von 4 ist also 1*1*2*3*4=24

In einer Programmiersprache wie Pascal, die rekursive Programmierung zulässt, kann man die Fakultät folgendermaßen eingeben:

Man definiert eine Funktion factorial, die eine Zahl x als Eingabewert bekommt. Diese Funktion multipliziert x mit dem Rückgabewert von factorial(x - 1) außer bei x = 0, dann liefert die Funktion das Ergebnis 1. Dies ist die Abbruchbedingung:

Rekursive Implementation der Fakultätsfunktion

function factorial(x: Integer): Integer;
begin
    if x = 0 then
        factorial := 1
    else
        factorial := x * factorial(x - 1);
end;

Mit der Startzahl x = 4 würde der Computer rechnen:

4 * (3 * (2 * (1 * factorial(0))))

heraus kommt dann das richtige Ergebnis, nämlich 24.

Binäre Suche

Die binäre Suche in einem vorsortierten Array lässt sich rekursiv implementieren. Wenn das mittlere Element kleiner als das gesuchte Element ist, wird die hintere Hälfte des Arrays rekursiv durchsucht. Wenn es größer als das gesuchte Element ist, wird die vordere Hälfte des Arrays rekursiv durchsucht. Ist es gleich dem gesuchten Element, ist die Suche beendet.

Die Abbruchbedingung für die Rekursion ist erfüllt, wenn das mittlere Element gleich dem gesuchten Element ist, die Suche also erfolgreich ist, oder wenn der Endindex kleiner als der Startindex ist, die Suche also erfolglos ist.

Die folgende Funktion (Methode) für die rekursive binäre Suche ist in der Programmiersprache C#:

int RekursiveBinaereSuche(int[] werte, int gesuchterWert, int startIndex, int endIndex)
{
    if (endIndex < startIndex)
    {
        // Wenn Element nicht gefunden, dann null zurückgeben
        return null;
    }
    int mittlererIndex = (startIndex + endIndex) / 2;
    if (werte[mittlererIndex] == gesuchterWert)
    {
        // Wenn Element gefunden, dann Index zurückgeben
        return mittlererIndex;
    }
    else
    {
        if (werte[mittlererIndex] < gesuchterWert)
        {
            // Rekursiver Aufruf der Funktion für die hintere Hälfte
            return RekursiveBinaereSuche(werte, gesuchterWert, mittlererIndex + 1, endIndex);
        }
        else
        {
            // Rekursiver Aufruf der Funktion für die vordere Hälfte
            return RekursiveBinaereSuche(werte, gesuchterWert, startIndex, mittlererIndex - 1);
        }
    }
}

Effizienz

Rekursive Programme haben in der Regel keine gute Performance. Durch die wiederholten Funktionsaufrufe (Inkarnationen) wird immer wieder derselbe Methodeneintrittscode bearbeitet und bei jeder Inkarnation der Kontext gesichert, was zu zusätzlichem Programmcode und höherem Arbeitsspeicherverbrauch führt. Alle rekursiven Algorithmen lassen sich jedoch auch durch iterative Programmierung implementieren und umgekehrt.

Fakultät

Man hätte die Fakultät auch so implementieren können:

function factorial(x: Integer): Integer;
    var i, number: Integer;
begin
    number := 1;

    for i := 1 to x do
        number := number * i;

    factorial := number;
end;

Hierbei gilt die Regel, dass für einfache Probleme eine iterative Implementierung häufig effizienter ist. So sollte z. B. auch die Fakultätsfunktion der Effizienz wegen in der Praxis iterativ implementiert werden. Bei komplizierten Problemstellungen (z. B. Aufgaben mit Bäumen) hingegen lohnt sich oftmals der Einsatz einer rekursiven Lösung, da für solche Probleme eine iterative Formulierung schnell sehr unübersichtlich – und ineffizient – werden kann, da im schlimmsten Fall der Stack durch den iterativen Algorithmus selbst verwaltet werden muss, was sonst der Prozessor direkt erledigt.

Nicht alle höheren Programmiersprachen lassen rekursive Aufrufe zu. Ein Beispiel dazu ist älteres Fortran. Ab Fortran 90 sind rekursive Aufrufe möglich. Andere Programmiersprachen sind dagegen grundsätzlich rekursiv (wie z. B. Prolog). Solche rekursiven Programmiersprachen und auch andere Sprachen wie z. B. Scheme setzen die Rekursion meistens effizient um.

Implementierung

Rekursion wird in der Regel durch einen Stack implementiert, der die Rücksprungadressen, aber auch alle lokalen Variablen und eventuell Funktionsergebnisse aufnimmt. Würde man, wie im obenstehenden Beispiel, die Fakultät von 4 berechnen, so würde jeder Aufruf folgende Informationen auf den Stack legen:

  1. Platz für Ergebnis
  2. Argument x
  3. Rücksprungadresse

Zunächst würde im Hauptprogramm also fac(4) aufgerufen und damit die folgenden Informationen auf den Stack gelegt:

Stapelanfang 1 Platz für Ergebnis
2 4 (Argument)
Stapelzeiger 3 Rücksprungadresse ins Hauptprogramm

Die Fakultätsfunktion prüft jetzt, ob das Argument 0 ist. Da dies nicht der Fall ist, wird 4*fac(3) berechnet. Zunächst muss also fac mit dem Argument 3 aufgerufen werden:

Stapelanfang 1 Platz für Ergebnis
2 4 (Argument)
3 Rücksprungadresse ins Hauptprogramm
4 Platz für Ergebnis
5 3 (Argument)
Stapelzeiger 6 Rücksprungadresse in die Fakultätsfunktion

Das Argument ist wieder ungleich 0, also geht’s weiter mit 3*fac(2).

Stapelanfang 1 Platz für Ergebnis
2 4 (Argument)
3 Rücksprungadresse ins Hauptprogramm
4 Platz für Ergebnis
5 3 (Argument)
6 Rücksprungadresse in die Fakultätsfunktion
7 Platz für Ergebnis
8 2 (Argument)
Stapelzeiger 9 Rücksprungadresse in die Fakultätsfunktion

Das Argument ist wieder ungleich 0, also2*fac(1).

Stapelanfang 1 Platz für Ergebnis
2 4 (Argument)
3 Rücksprungadresse ins Hauptprogramm
4 Platz für Ergebnis
5 3 (Argument)
6 Rücksprungadresse in die Fakultätsfunktion
7 Platz für Ergebnis
8 2 (Argument)
9 Rücksprungadresse in die Fakultätsfunktion
10 Platz für Ergebnis
11 1 (Argument)
Stapelzeiger 12 Rücksprungadresse in die Fakultätsfunktion

Das Argument ist wieder ungleich 0, also1*fac(0).

Stapelanfang 1 Platz für Ergebnis
2 4 (Argument)
3 Rücksprungadresse ins Hauptprogramm
4 Platz für Ergebnis
5 3 (Argument)
6 Rücksprungadresse in die Fakultätsfunktion
7 Platz für Ergebnis
8 2 (Argument)
9 Rücksprungadresse in die Fakultätsfunktion
10 Platz für Ergebnis
11 1 (Argument)
12 Rücksprungadresse in die Fakultätsfunktion
13 Platz für Ergebnis
14 0 (Argument)
Stapelzeiger 15 Rücksprungadresse in die Fakultätsfunktion

Jetzt ist das Argument 0, das Ergebnis also 1. Wir holen die Rücksprungadresse und das Argument vom Stack und schreiben die 1 in den dafür vorgesehenen Platz. Der Rücksprung führt in die Fakultätsfunktion zurück:

Stapelanfang 1 Platz für Ergebnis
2 4 (Argument)
3 Rücksprungadresse ins Hauptprogramm
4 Platz für Ergebnis
5 3 (Argument)
6 Rücksprungadresse in die Fakultätsfunktion
7 Platz für Ergebnis
8 2 (Argument)
9 Rücksprungadresse in die Fakultätsfunktion
10 Platz für Ergebnis
11 1 (Argument)
12 Rücksprungadresse in die Fakultätsfunktion
Stapelzeiger 13 1 (Ergebnis)

Jetzt kann man das Ergebnis mit dem Argument multiplizieren (1*1). Das neue Ergebnis ist wieder 1. Die Rücksprungadresse und das Argument werden vom Stack geholt und das neue Ergebnis in den dafür vorgesehenen Platz geschrieben. Rücksprung in die Fakultätsfunktion:

Stapelanfang 1 Platz für Ergebnis
2 4 (Argument)
3 Rücksprungadresse ins Hauptprogramm
4 Platz für Ergebnis
5 3 (Argument)
6 Rücksprungadresse in die Fakultätsfunktion
7 Platz für Ergebnis
8 2 (Argument)
9 Rücksprungadresse in die Fakultätsfunktion
Stapelzeiger 10 1 (Ergebnis)

Wiederum wird das Ergebnis mit dem Argument multipliziert (1*2). Zurück in die Fakultätsfunktion:

Stapelanfang 1 Platz für Ergebnis
2 4 (Argument)
3 Rücksprungadresse ins Hauptprogramm
4 Platz für Ergebnis
5 3 (Argument)
6 Rücksprungadresse in die Fakultätsfunktion
Stapelzeiger 7 2 (Ergebnis)

Das Ergebnis wird mit dem Argument multipliziert (2*3). Zurück in die Fakultätsfunktion:

Stapelanfang 1 Platz für Ergebnis
2 4 (Argument)
3 Rücksprungadresse ins Hauptprogramm
Stapelzeiger 4 6 (Ergebnis)

Das Ergebnis wird mit dem Argument multipliziert (6*4). Zurück ins Hauptprogramm

Stapelanfang
Stapelzeiger
1 24 (Ergebnis)

Das Hauptprogramm muss dann nur noch das Ergebnis 24 vom Stack holen.

Siehe auch

Wikibooks: Rekursive Labyrinthe – Lern- und Lehrmaterialien

Read other articles:

Lockheed CorporationNasibMerger dengan Martin MariettaPenerusLockheed MartinDidirikan1912Ditutup1995KantorpusatCalabasas, California Lockheed Corporation (awalnya bernama Loughead Aircraft Manufacturing Company) adalah perusahaan kedirgantaraan Amerika Serikat yang didirikan pada tahun 1912. Perusahaan ini kemudian pada tahun 1995 merger dengan Martin Marietta membentuk Lockheed Martin. Divisi Aeronautical Systems Group Lockheed-California Company (CALAC), Burbank, California. Lockheed-Georgi...

 

American baseball spectator Freddy SchumanFreddy Schuman holding one of his signs near the Bleachers entrance to Yankee StadiumBornMay 23, 1925New York, United StatesDiedOctober 17, 2010(2010-10-17) (aged 85)Manhattan, New York, United StatesOther namesFreddy SezKnown forUnofficial promoter of the Yankees c. 1988 to 2010 Freddy Schuman (May 23, 1925 – October 17, 2010), better known as Freddy Sez or Freddy Sez, was an American superfan of the New York Yankees. He was kn...

 

Chinese Sportscar Racing Team Jackie Chan DC RacingFounded20 August 2015 (2015-08-20)Founder(s)David ChengJackie ChanBaseWuhanFormer seriesAsian Le Mans SeriesWeatherTech SportsCar ChampionshipFIA World Endurance ChampionshipTeams'Championships2 Asian Le Mans Series (2015–16), (2017–18)Drivers'Championships2 Asian Le Mans Series (2015–16), (2017–18) Jackie Chan DC Racing, formerly known as DC Racing, is a racing team that competed in the FIA World Endurance Championship...

48th Fighter WingStatue of Liberty Wing48th Fighter Wing EmblemActive10 July 1952–presentCountry United StatesAllegianceUnited States of AmericaBranch United States Air ForceRoleFighterSizeWingPart ofUnited States Air Forces in Europe – Air Forces AfricaGarrison/HQRAF LakenheathNickname(s)Statue of Liberty WingEngagements1991 Gulf War (Defense of Saudi Arabia; Liberation of Kuwait)Kosovo Air CampaignDecorationsNavy Meritorious Unit CommendationAir Force Outstanding Unit Aw...

 

Chinese wrap dish Tofu skin rollSteamed Tofu skin rollAlternative namesTofu rollCourseDim SumPlace of originChinaMain ingredientsbean curd, various vegetables or meat filling  Media: Tofu skin roll Fried versionTraditional Chinese腐皮捲Simplified Chinese腐皮卷Literal meaningtofu skin rollTranscriptionsStandard MandarinHanyu Pinyinfu3 pi2 quan1Yue: CantoneseJyutpingfu6 pei4 gyun2Steamed versionTraditional Chinese鮮竹捲Simplified Chinese鲜竹卷TranscriptionsStandar...

 

Erik II Emune Erik II yang Mengesankan (bahasa Denmark: Erik II Emune; skt. 1090 – 18 September 1137) merupakan seorang Raja Denmark antara 1134 dan 1137. Erik adalah putra tidak sah Raja Erik I dari Denmark dan seorang gundik yang tidak diketahui,[1] yang bertakhta di Denmark pada 1095 hingga 1103. Ia diberikan beberapa pulau di Denmark oleh saudara tirinya, Knud Lavard,[2] dan menjabat sebagai jarl di Møn, Lolland, dan Falster.[3] Erik yang mengesankan menenta...

蔣中正中華民國總統府官方肖像(摄于1955年) 中華民國第1-5任總統選舉:1948、1954、1960、1966、1972任期1950年3月1日復行視事—1975年4月5日副总统李宗仁陳誠嚴家淦前任李宗仁 → 閻錫山(代理)蔣中正(正任)继任嚴家淦任期1948年5月20日—1949年1月21日下野副总统李宗仁前任首任继任李宗仁(代理)蔣中正(正任) 中華民國第2、4任國民政府委員會主席任期1943年8月...

 

هذه المقالة يتيمة إذ تصل إليها مقالات أخرى قليلة جدًا. فضلًا، ساعد بإضافة وصلة إليها في مقالات متعلقة بها. (يوليو 2019) جيرد كريستيانسن   معلومات شخصية الميلاد 1 أغسطس 1955 (69 سنة)  هارستاد  مواطنة النرويج  الحياة العملية المهنة نقابية  المواقع IMDB صفحتها على IMDB  تعد...

 

2021 American film by Adam Wingard This article is about the 2021 film. For the 1962 film, see King Kong vs. Godzilla. Godzilla vs. KongRelease posterDirected byAdam WingardScreenplay by Eric Pearson Max Borenstein Story by Terry Rossio Michael Dougherty Zach Shields Based onGodzilla and Mechagodzillaby Toho Co., LtdProduced by Thomas Tull Jon Jashni Brian Rogers Mary Parent Alex Garcia Eric McLeod Starring Alexander Skarsgård Millie Bobby Brown Rebecca Hall Brian Tyree Henry Shun Oguri Eiza...

القوات البرية اليمنية شارة القوات البرية اليمنية الدولة الجمهورية اليمنية الإنشاء تأسيس الجيش المظفر في 1918 تأسيس جيش الشمال في 1962 تأسيس جيش الجنوب في 1967 دمج الجيشين في 1990 عام الوحدة النوع قوات برية الحجم 80,000 جزء من من القوات المسلحة اليمنية وزارة الدفاع العاصمة صنعاء منا�...

 

Komite psikoanalis pada 1922 (dari kiri ke kanan): Otto Rank, Sigmund Freud, Karl Abraham, Max Eitingon, Sándor Ferenczi, Ernest Jones, Hanns Sachs Max Eitingon (26 Juni 1881 – 30 Juli 1943) adalah seorang dokter dan psikoanalis Belarusia-Jerman. Ia dikenal karena membuat parameter institusional dari pendidikan dan pelatihan psikoanalitik.[1] Karya 'Genie, Talent und Psychoanalyse', Zentralblatt für Psychoanalyse 2 (1912) 539-540. 'Gott und Vater', Imago 3 (1914), 90...

 

La riflettanza misura, in ottica, la capacità di riflettere parte della luce incidente su una data superficie o materiale. Essendo quindi il rapporto tra intensità del flusso radiante riflesso e intensità del flusso radiante incidente, è una grandezza adimensionale. Indice 1 Descrizione 2 Modelli di riflessione 3 Esempio pratico sulla luce 4 Esempi 5 Note 6 Bibliografia 7 Voci correlate 8 Altri progetti 9 Collegamenti esterni Descrizione Sottoposto ad irraggiamento termico o luminoso, ogn...

9th season of the Premier League This article needs additional citations for verification. Please help improve this article by adding citations to reliable sources. Unsourced material may be challenged and removed.Find sources: 2000–01 FA Premier League – news · newspapers · books · scholar · JSTOR (May 2015) (Learn how and when to remove this message) Football league seasonFA Premier LeagueSeason2000–01Dates19 August 2000 – 19 May 2001Champions...

 

Reバース for you ジャンル トレーディングカードゲーム ゲーム ゲームジャンル トレーディングカードゲーム 発売元 ブシロード 発売日 2020年3月 - ラジオ:ReバースRADIO〜修行編〜 → りばらじ 配信期間 2019年10月8日 - 配信サイト 響 - HiBiKi Radio Station - パーソナリティ ReバースRADIO徳井青空、佐々木未来りばらじ西尾夕香 アニメ:りばあす 原作 ブシロード、西あすか 原案 ...

 

Questa voce o sezione sull'argomento centri abitati della Lombardia non cita le fonti necessarie o quelle presenti sono insufficienti. Puoi migliorare questa voce aggiungendo citazioni da fonti attendibili secondo le linee guida sull'uso delle fonti. Segui i suggerimenti del progetto di riferimento. Questa voce o sezione sull'argomento Lombardia non è ancora formattata secondo gli standard. Contribuisci a migliorarla secondo le convenzioni di Wikipedia. Segui i suggerimenti del pr...

武汉 总览 武汉经济 武汉政府 武汉教育 武汉交通 武汉规划 武汉人口 武汉地理 武汉氣候 武汉生態 武汉山峰 武汉山脈 武汉水系 武汉河流 武汉歷史 武汉老城 武汉租界 宋朝時期 元朝時期 明朝時期 清朝時期 北洋政府 国民政府 日占時期 共和国时期 武汉文化 武汉方言 武汉電影 武汉藝術 武汉文學 武汉建筑 武汉桥梁 武汉戲劇 武汉曲艺 武汉宗教 武汉民俗 武汉媒體 武汉小吃...

 

2006 single by Crime Mob featuring Lil ScrappyRock Yo HipsSingle by Crime Mob featuring Lil Scrappyfrom the album Hated on Mostly ReleasedAugust 29, 2006 (2006-08-29)Recorded2006StudioPatchWerk Recording Studios (Atlanta, GA)GenreCrunkLength3:48LabelCrunk Incorporated Reprise, Warner Bros.Songwriter(s)Jonathan LewisBrittany CarpenteroVenetia LewisJarques UsherChris HendersonAlphonce SmithProducer(s)Lil' JayCrime Mob singles chronology Knuck If You Buck (2004) Rock Yo Hips (...

 

Pour un article plus général, voir Records du monde d'athlétisme. Record du monde dumarathon Kelvin Kiptum, actuel détenteur du record du monde masculin du marathon. Caractéristiques du record Discipline Marathonathlétisme Instancehomologatrice World Athletics Genre Hommes / Femmes Portée Monde Record actuel masculin Valeur 2 h 0 min 35 s Titulaire(s) Kelvin Kiptum Kenya Date du record 8 octobre 2023 Circonstance Marathon de Chicago Site Chicago États-Unis Re...

Italian composers Rossini, Bellini, Ricci, Mercadante and Donizetti Music of Italy Timeline General topics Opera houses Music conservatories Terminology Genres Classical (Opera) Pop Rock (Hardcore · New Wave · Progressive rock) Disco House Dance Folk Hip hop Jazz Specific forms Gregorian chant Media and performance Music awards Sanremo Music Festival (festival and awards) Festival di Napoli (festival and awards) Tenco Plates and Awards Lunezia Awards Music Awards Coca Cola Summer Festival ...

 

Dieser Artikel behandelt einzelne Lautsprecher (siehe Bild) als technische Bauteile. Zur Einheit von Lautsprecher(n) und einem Gehäuse siehe Lautsprecherbox. Dynamischer Lautsprecher (Tauchspulenprinzip) mit Papier-Konusmembran und Gummi-Sicke Lautsprecher (anhörenⓘ/?) sind Schallwandler, die aus einem elektrischen Eingangssignal Schall erzeugen. Sie dienen meist der Wiedergabe von Sprache oder Musik als Luftschall und sind daher auf Frequenzen im Hörbereich des Menschen ausgerichtet (2...