Considérez un vieux problème bien connu :
En mathématiques, le plus grand diviseur commun (pgcd)… de deux ou plusieurs entiers non nuls, est le plus grand entier positif qui divise les nombres sans reste.
La définition de pgcd est étonnamment simple:
où mod est l' opérateur modulo (c'est-à-dire le reste après la division entière).
En anglais, cette définition dit que le plus grand diviseur commun de tout nombre et zéro est ce nombre, et le plus grand diviseur commun de deux nombres m et n est le plus grand diviseur commun de n et le reste après avoir divisé m par n .
Si vous souhaitez savoir pourquoi cela fonctionne, consultez l'article de Wikipedia sur l' algorithme euclidien .
Calculons gcd (10, 8) comme exemple. Chaque pas est égal à celui juste avant:
- pgcd (10, 8)
- pgcd (10, 10 mod 8)
- pgcd (8, 2)
- pgcd (8, 8 mod 2)
- pgcd (2, 0)
- 2
Dans la première étape, 8 n'est pas égal à zéro, donc la deuxième partie de la définition s'applique. 10 mod 8 = 2 car 8 entre une fois dans 10 avec un reste de 2. A l'étape 3, la deuxième partie s'applique à nouveau, mais cette fois 8 mod 2 = 0 car 2 divise 8 sans reste. À l'étape 5, le deuxième argument est 0, donc la réponse est 2.
Avez-vous remarqué que pgcd apparaît sur les côtés gauche et droit du signe égal? Un mathématicien dirait que cette définition est récursive parce que l'expression que vous définissez se répète dans sa définition.
Les définitions récursives ont tendance à être élégantes. Par exemple, une définition récursive pour la somme d'une liste est
sum l =
if empty(l)
return 0
else
return head(l) + sum(tail(l))
où head
est le premier élément d'une liste et tail
le reste de la liste. Notez que sum
se reproduit dans sa définition à la fin.
Vous préférez peut-être la valeur maximale dans une liste à la place:
max l =
if empty(l)
error
elsif length(l) = 1
return head(l)
else
tailmax = max(tail(l))
if head(l) > tailmax
return head(l)
else
return tailmax
Vous pouvez définir la multiplication d'entiers non négatifs de manière récursive pour en faire une série d'ajouts:
a * b =
if b = 0
return 0
else
return a + (a * (b - 1))
Si cela n'a pas de sens de transformer la multiplication en une série d'ajouts, essayez de développer quelques exemples simples pour voir comment cela fonctionne.
Le tri par fusion a une belle définition récursive:
sort(l) =
if empty(l) or length(l) = 1
return l
else
(left,right) = split l
return merge(sort(left), sort(right))
Les définitions récursives sont omniprésentes si vous savez ce qu'il faut rechercher. Remarquez comment toutes ces définitions ont des cas de base très simples, par exemple , gcd (m, 0) = m. Les cas récursifs réduisent le problème pour arriver aux réponses faciles.
Avec cette compréhension, vous pouvez maintenant apprécier les autres algorithmes dans l'article de Wikipedia sur la récursivité !