logo

Čo je rekurzia chvosta

Rekurzia chvosta je definovaná ako rekurzívna funkcia, v ktorej je rekurzívne volanie posledným príkazom, ktorý funkcia vykoná. Po rekurznom volaní teda v podstate nezostane nič na vykonanie.

Napríklad nasledujúca funkcia print() v jazyku C++ je rekurzívna.



C








// An example of tail recursive function> void> print(>int> n)> {> >if> (n <0)> >return>;> >printf>(>'%d '>, n);> >// The last executed statement is recursive call> >print(n - 1);> }>

>

>

C++




// An example of tail recursive function> static> void> print(>int> n)> {> >if> (n <0)> >return>;> >cout <<>' '> << n;> > >// The last executed statement is recursive call> >print(n - 1);> }> // This code is contributed by Aman Kumar>

>

>

Java




// An example of tail recursive function> static> void> print(>int> n)> {> >if> (n <>0>)> >return>;> >System.out.print(>' '> + n);> >// The last executed statement> >// is recursive call> >print(n ->1>);> }> // This code is contributed by divyeh072019>

>

>

Python3




# An example of tail recursive function> def> prints(n):> >if> (n <>0>):> >return> >print>(>str>(n), end>=>' '>)> ># The last executed statement is recursive call> >prints(n>->1>)> ># This code is contributed by Pratham76> ># improved by ashish2021>

>

>

C#




// An example of tail recursive function> static> void> print(>int> n)> {> >if> (n <0)> >return>;> >Console.Write(>' '> + n);> >// The last executed statement> >// is recursive call> >print(n - 1);> }> // This code is contributed by divyeshrabadiya07>

>

>

Javascript




> // An example of tail recursive function> function> print(n)> {> >if> (n <0)> >return>;> > >document.write(>' '> + n);> > >// The last executed statement> >// is recursive call> >print(n - 1);> }> // This code is contributed by Rajput-Ji> >

>

>

Časová zložitosť: O(n)
Pomocný priestor: O(n)

Potreba rekurzie chvosta:

Koncové rekurzívne funkcie sa považujú za lepšie ako nekoncové rekurzívne funkcie, pretože rekurziu chvosta môže kompilátor optimalizovať.

Kompilátory zvyčajne vykonávajú rekurzívne procedúry pomocou a stoh . Tento zásobník obsahuje všetky príslušné informácie, vrátane hodnôt parametrov, pre každé rekurzívne volanie. Keď sa volá procedúra, sú jej informácie tlačil do zásobníka a keď funkcia skončí, informácia je prasklo mimo zásobníka. Takže pre non-tail-rekurzívne funkcie, hĺbka stohu (maximálne množstvo miesta v zásobníku využité kedykoľvek počas kompilácie) je viac.

Myšlienka používaná kompilátormi na optimalizáciu koncových rekurzívnych funkcií je jednoduchá, keďže rekurzívne volanie je posledným príkazom, v aktuálnej funkcii už nie je čo robiť, takže ukladanie zásobníkového rámca aktuálnej funkcie je zbytočné (pozrite si viac podrobnosti).

Je možné napísať nerekurzívnu funkciu ako chvostovú rekurzívnu, aby sa optimalizovala?

Zvážte nasledujúcu funkciu na výpočet faktoriálu n.

Je to non-tail-rekurzívna funkcia. Aj keď to na prvý pohľad vyzerá ako rekurzívny chvost. Ak sa pozrieme bližšie, vidíme, že hodnota vrátená faktom (n-1) sa používa v fakt(n) . Takže výzva fakt(n-1) nie je posledná vec, ktorú urobil fakt(n) .

C++




#include> using> namespace> std;> // A NON-tail-recursive function. The function is not tail> // recursive because the value returned by fact(n-1) is used> // in fact(n) and call to fact(n-1) is not the last thing> // done by fact(n)> unsigned>int> fact(unsigned>int> n)> {> >if> (n <= 0)> >return> 1;> >return> n * fact(n - 1);> }> // Driver program to test above function> int> main()> {> >cout << fact(5);> >return> 0;> }>

>

>

Java




class> GFG {> >// A NON-tail-recursive function.> >// The function is not tail> >// recursive because the value> >// returned by fact(n-1) is used> >// in fact(n) and call to fact(n-1)> >// is not the last thing done by> >// fact(n)> >static> int> fact(>int> n)> >{> >if> (n ==>0>)> >return> 1>;> >return> n * fact(n ->1>);> >}> >// Driver program> >public> static> void> main(String[] args)> >{> >System.out.println(fact(>5>));> >}> }> // This code is contributed by Smitha.>

>

>

Python3




# A NON-tail-recursive function.> # The function is not tail> # recursive because the value> # returned by fact(n-1) is used> # in fact(n) and call to fact(n-1)> # is not the last thing done by> # fact(n)> def> fact(n):> >if> (n>=>=> 0>):> >return> 1> >return> n>*> fact(n>->1>)> # Driver program to test> # above function> if> __name__>=>=> '__main__'>:> >print>(fact(>5>))> # This code is contributed by Smitha.>

>

>

C#




using> System;> class> GFG {> >// A NON-tail-recursive function.> >// The function is not tail> >// recursive because the value> >// returned by fact(n-1) is used> >// in fact(n) and call to fact(n-1)> >// is not the last thing done by> >// fact(n)> >static> int> fact(>int> n)> >{> >if> (n == 0)> >return> 1;> >return> n * fact(n - 1);> >}> >// Driver program to test> >// above function> >public> static> void> Main() { Console.Write(fact(5)); }> }> // This code is contributed by Smitha>

>

>

PHP




// A NON-tail-recursive function. // The function is not tail // recursive because the value // returned by fact(n-1) is used in // fact(n) and call to fact(n-1) is // not the last thing done by fact(n) function fact( $n) { if ($n == 0) return 1; return $n * fact($n - 1); } // Driver Code echo fact(5); // This code is contributed by Ajit ?>>

>

>

Javascript




> // A NON-tail-recursive function.> // The function is not tail> // recursive because the value> // returned by fact(n-1) is used> // in fact(n) and call to fact(n-1)> // is not the last thing done by> // fact(n)> function> fact(n)> {> >if> (n == 0)> >return> 1;> > >return> n * fact(n - 1);> }> // Driver code> document.write(fact(5));> // This code is contributed by divyeshrabadiya07> >

>

>

Výkon

120>

Časová zložitosť: O(n)
Pomocný priestor: O(n)

Vyššie uvedená funkcia môže byť napísaná ako koncová rekurzívna funkcia. Myšlienkou je použiť ešte jeden argument a akumulovať faktoriálnu hodnotu v druhom argumente. Keď n dosiahne 0, vráťte akumulovanú hodnotu.

Nižšie je uvedená implementácia pomocou chvostovej rekurzívnej funkcie.

C++




#include> using> namespace> std;> // A tail recursive function to calculate factorial> unsigned factTR(unsigned>int> n, unsigned>int> a)> {> >if> (n <= 1)> >return> a;> >return> factTR(n - 1, n * a);> }> // A wrapper over factTR> unsigned>int> fact(unsigned>int> n) {>return> factTR(n, 1); }> // Driver program to test above function> int> main()> {> >cout << fact(5);> >return> 0;> }>

>

>

Java




// Java Code for Tail Recursion> class> GFG {> >// A tail recursive function> >// to calculate factorial> >static> int> factTR(>int> n,>int> a)> >{> >if> (n <=>0>)> >return> a;> >return> factTR(n ->1>, n * a);> >}> >// A wrapper over factTR> >static> int> fact(>int> n) {>return> factTR(n,>1>); }> >// Driver code> >static> public> void> main(String[] args)> >{> >System.out.println(fact(>5>));> >}> }> // This code is contributed by Smitha.>

>

java reťazec indexof
>

Python3




# A tail recursive function> # to calculate factorial> def> fact(n, a>=>1>):> >if> (n <>=> 1>):> >return> a> >return> fact(n>-> 1>, n>*> a)> # Driver program to test> # above function> print>(fact(>5>))> # This code is contributed> # by Smitha> # improved by Ujwal, ashish2021>

>

>

C#




// C# Code for Tail Recursion> using> System;> class> GFG {> >// A tail recursive function> >// to calculate factorial> >static> int> factTR(>int> n,>int> a)> >{> >if> (n <= 0)> >return> a;> >return> factTR(n - 1, n * a);> >}> >// A wrapper over factTR> >static> int> fact(>int> n) {>return> factTR(n, 1); }> >// Driver code> >static> public> void> Main()> >{> >Console.WriteLine(fact(5));> >}> }> // This code is contributed by Ajit.>

>

>

PHP




// A tail recursive function // to calculate factorial function factTR($n, $a) { if ($n <= 0) return $a; return factTR($n - 1, $n * $a); } // A wrapper over factTR function fact($n) { return factTR($n, 1); } // Driver program to test // above function echo fact(5); // This code is contributed // by Smitha ?>>

>

>

Javascript




> // Javascript Code for Tail Recursion> // A tail recursive function> // to calculate factorial> function> factTR(n, a)> {> >if> (n <= 0)> >return> a;> > >return> factTR(n - 1, n * a);> }> > // A wrapper over factTR> function> fact(n)> {> >return> factTR(n, 1);> }> // Driver code> document.write(fact(5));> // This code is contributed by rameshtravel07> > >

>

>

Výkon

120>

Časová zložitosť: O(n)
Pomocný priestor: O(1)

Ďalšie články na túto tému:

  • Eliminácia chvostového volania
  • QuickSort Tail Call Optimization (zníženie miesta pre najhorší prípad na Log n )