Thema indholdsfortegnelse -- Tastaturgenvej: 'u'  Forrige tema i denne lektion -- Tastaturgenvej: 'p'  Næste slide i denne lektion -- Tastaturgenvej: 'n'Funktioner
14.  Rekursive funktioner

En rekursiv funktion er kendetegnet ved, at den kalder sig selv. Men som det mest væsentlige, er rekursive funktioner udtryk for en problemløsning, hvor delproblemerne ligner det overordnede problem.

Vi introducerer rekursion i dette kapitel. I en senere lektion, startende i kapitel 32, vender vi tilbage til rekursion med fornyet styrke.

14.1 Rekursive funktioner
 

14.1.  Rekursive funktioner
Indhold   Op Forrige Næste   Slide Aggregerede slides    Stikord Programindeks Opgaveindeks 

Først gør vi os de essentielle iagttagelser om rekursion, problemer som har rekursivt forekommende delproblemer:

En rekursiv funktion kalder sig selv

Rekursive funktioner er nyttige når et problem kan opdeles i delproblemer, hvoraf nogle har samme natur som problemet selv

Som det første eksempel programmerer vi fakultetsfunktionen. Hvis vi af bekvemmelighed her kalder fakultetsfunktionen for f, gælder at f(n) = n . (n-1) . (n-2) . ... 2 . 1. Dette kan også udtrykkes rekursivt som følger:

Denne rekursive formel er udtrykt direkte i C funktionen factorial i program 14.1. Det rekursive kald er fremhævet med rødt.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>

unsigned long factorial(unsigned long n){
  if (n == 0)
    return 1;
  else return n * factorial(n - 1);
}

int main(void) {
  unsigned long k;

  for (k = 1; k <= 12; k++)
    printf("%-20lu %20lu\n", k, factorial(k));
  
  return 0;
}
Program 14.1    Et program med en rekursivt defineret fakultetsfunktion.

Som de fleste nok ved i forvejen vokser fakultetsfunktionen ganske voldsomt. Så voldsomt at vi højst kan beregne factorial(12), selv med tal i typen long. Vi viser outputtet af program 14.1 i program 14.2.

1
2
3
4
5
6
7
8
9
10
11
12
1                                       1
2                                       2
3                                       6
4                                      24
5                                     120
6                                     720
7                                    5040
8                                   40320
9                                  362880
10                                3628800
11                               39916800
12                              479001600
Program 14.2    Output fra ovenstående program.

Som endnu et eksempel viser vi en rekursiv udgave af rodsøgningsfunktionen findRootBetween i program 14.3. Vi mødte den iterative (gentagende) udgave i program 13.1. Gentagelsen blev i dette program lavet med en while løkke.

1
2
3
4
5
6
7
8
9
double findRootBetween(double l, double u){
  if (isSmallNumber(f(middleOf(l,u))))
     return middleOf(l,u);
  else if (sameSign(f(middleOf(l,u)), f(u)))
     return findRootBetween(l, middleOf(l,u));
  else if (!sameSign(f(middleOf(l,u)), f(u)))
     return findRootBetween(middleOf(l,u),u);
  else exit (-1);
}
Program 14.3    En rekursiv version af funktionen findRootBetween.

Vi lægger mærke til, at der ikke anvendes nogen form for løkker i findRootBetween som programmeret i program 14.3. Gentagelsen bestyres af at funktionen kalder sig selv et tilstrækkeligt antal gange, indtil vi er tæt nok på roden.

Genereret: Onsdag 7. Juli 2010, 15:10:47
Thema indholdsfortegnelse -- Tastaturgenvej: 'u'  Forrige tema i denne lektion -- Tastaturgenvej: 'p'  Næste slide i denne lektion -- Tastaturgenvej: 'n'