From 1d2e86d287ceece27fcd7f617fd1e9c096ce79d9 Mon Sep 17 00:00:00 2001 From: rztprog Date: Sat, 6 Jul 2019 12:39:27 +0200 Subject: [PATCH] Translate recusion in french language --- .../01-recursion/01-sum-to/solution.md | 12 +- .../01-recursion/01-sum-to/task.md | 22 +- .../01-recursion/02-factorial/solution.md | 6 +- .../01-recursion/02-factorial/task.md | 12 +- .../03-fibonacci-numbers/solution.md | 62 ++-- .../01-recursion/03-fibonacci-numbers/task.md | 16 +- .../04-output-single-linked-list/solution.md | 26 +- .../04-output-single-linked-list/task.md | 10 +- .../solution.md | 16 +- .../task.md | 6 +- .../01-recursion/article.md | 295 +++++++++--------- 11 files changed, 242 insertions(+), 241 deletions(-) diff --git a/1-js/06-advanced-functions/01-recursion/01-sum-to/solution.md b/1-js/06-advanced-functions/01-recursion/01-sum-to/solution.md index 3a281ef3f..7b4898157 100644 --- a/1-js/06-advanced-functions/01-recursion/01-sum-to/solution.md +++ b/1-js/06-advanced-functions/01-recursion/01-sum-to/solution.md @@ -1,4 +1,4 @@ -The solution using a loop: +La solution utilisant une boucle: ```js run function sumTo(n) { @@ -12,7 +12,7 @@ function sumTo(n) { alert( sumTo(100) ); ``` -The solution using recursion: +La solution utilisant la récursion: ```js run function sumTo(n) { @@ -23,7 +23,7 @@ function sumTo(n) { alert( sumTo(100) ); ``` -The solution using the formula: `sumTo(n) = n*(n+1)/2`: +La solution utilisant la formule: `sumTo(n) = n*(n+1)/2`: ```js run function sumTo(n) { @@ -33,8 +33,8 @@ function sumTo(n) { alert( sumTo(100) ); ``` -P.S. Naturally, the formula is the fastest solution. It uses only 3 operations for any number `n`. The math helps! +P.S. Naturellement, la formule est la solution la plus rapide. Elle n’utilise que 3 opérations pour n’importe quel nombre `n`. Le calcul aide! -The loop variant is the second in terms of speed. In both the recursive and the loop variant we sum the same numbers. But the recursion involves nested calls and execution stack management. That also takes resources, so it's slower. +La variante de boucle est la seconde en termes de vitesse. Dans la variante récursive et la variante de boucle, nous additionnons les mêmes nombres. Mais la récursion implique des appels imbriqués et la gestion de la pile d'exécution. Donc, cela prend des ressources, donc c'est plus lent. -P.P.S. Some engines support the "tail call" optimization: if a recursive call is the very last one in the function (like in `sumTo` above), then the outer function will not need to resume the execution, so the engine doesn't need to remember its execution context. That removes the burden on memory, so counting `sumTo(100000)` becomes possible. But if the JavaScript engine does not support tail call optimization (most of them don't), there will be an error: maximum stack size exceeded, because there's usually a limitation on the total stack size. +P.P.S. Certains moteurs prennent en charge l'optimisation du "tail call (dernier appel)": si un appel récursif est le dernier de la fonction (comme dans la somme ci-dessus), le moteur n'a pas besoin de reprendre son contexte d'exécution. Cela supprime la charge en mémoire, donc compter `sumTo (100000)` devient possible. Toutefois, si le moteur JavaScript ne prend pas en charge l'optimisation des appels en bout de ligne, il y aura une erreur: maximum stack size exceeded (la taille maximale de la pile est dépassée), car la taille totale de la pile est généralement limitée. diff --git a/1-js/06-advanced-functions/01-recursion/01-sum-to/task.md b/1-js/06-advanced-functions/01-recursion/01-sum-to/task.md index cabc13290..4a6bb3b17 100644 --- a/1-js/06-advanced-functions/01-recursion/01-sum-to/task.md +++ b/1-js/06-advanced-functions/01-recursion/01-sum-to/task.md @@ -2,11 +2,11 @@ importance: 5 --- -# Sum all numbers till the given one +# Additionner tous les nombres jusqu'à celui donné -Write a function `sumTo(n)` that calculates the sum of numbers `1 + 2 + ... + n`. +Écrire une fonction `sumTo(n)` qui calcule la somme des nombres `1 + 2 + ... + n`. -For instance: +Par exemple: ```js no-beautify sumTo(1) = 1 @@ -17,20 +17,20 @@ sumTo(4) = 4 + 3 + 2 + 1 = 10 sumTo(100) = 100 + 99 + ... + 2 + 1 = 5050 ``` -Make 3 solution variants: +Faites 3 variantes de solution: -1. Using a for loop. -2. Using a recursion, cause `sumTo(n) = n + sumTo(n-1)` for `n > 1`. -3. Using the [arithmetic progression](https://en.wikipedia.org/wiki/Arithmetic_progression) formula. +1. Utiliser une boucle for. +2. Utiliser une récursion, avec `sumTo(n) = n + sumTo(n-1)` pour `n > 1`. +3. Utiliser la formule de [progression arithmétique](https://en.wikipedia.org/wiki/Arithmetic_progression). -An example of the result: +Un exemple de résultat: ```js -function sumTo(n) { /*... your code ... */ } +function sumTo(n) { /*... ton code ... */ } alert( sumTo(100) ); // 5050 ``` -P.S. Which solution variant is the fastest? The slowest? Why? +P.S. Quelle solution est la plus rapide? La plus lente? Pourquoi? -P.P.S. Can we use recursion to count `sumTo(100000)`? +P.P.S. Peut-on utiliser la récursion pour compter `sumTo(100000)`? diff --git a/1-js/06-advanced-functions/01-recursion/02-factorial/solution.md b/1-js/06-advanced-functions/01-recursion/02-factorial/solution.md index 59040a2b7..50ede5993 100644 --- a/1-js/06-advanced-functions/01-recursion/02-factorial/solution.md +++ b/1-js/06-advanced-functions/01-recursion/02-factorial/solution.md @@ -1,6 +1,6 @@ -By definition, a factorial is `n!` can be written as `n * (n-1)!`. +Par définition, une factorielle est `n!` peut être écrit `n * (n-1)!`. -In other words, the result of `factorial(n)` can be calculated as `n` multiplied by the result of `factorial(n-1)`. And the call for `n-1` can recursively descend lower, and lower, till `1`. +En d'autres termes, le résultat de `factorial(n)` peut être calculé comme `n` multiplié par le résultat de `factorial(n-1)`. Et l'appel de `n-1` peut récursivement descendre plus bas, et plus bas, jusqu'à `1`. ```js run function factorial(n) { @@ -10,7 +10,7 @@ function factorial(n) { alert( factorial(5) ); // 120 ``` -The basis of recursion is the value `1`. We can also make `0` the basis here, doesn't matter much, but gives one more recursive step: +La base de la récursivité est la valeur `1`. Nous pouvons aussi faire de `0` la base ici, ça importe peu, mais donne une étape récursive supplémentaire: ```js run function factorial(n) { diff --git a/1-js/06-advanced-functions/01-recursion/02-factorial/task.md b/1-js/06-advanced-functions/01-recursion/02-factorial/task.md index d2aef2d90..62b271b4c 100644 --- a/1-js/06-advanced-functions/01-recursion/02-factorial/task.md +++ b/1-js/06-advanced-functions/01-recursion/02-factorial/task.md @@ -2,17 +2,17 @@ importance: 4 --- -# Calculate factorial +# Calcule factoriel -The [factorial](https://en.wikipedia.org/wiki/Factorial) of a natural number is a number multiplied by `"number minus one"`, then by `"number minus two"`, and so on till `1`. The factorial of `n` is denoted as `n!` +Le [factorielle](https://en.wikipedia.org/wiki/Factorial) d'un nombre naturel est multiplié par `"nombre moins un"`, ensuite par `"nombre moins deux"`, et ainsi de suite jusqu'à `1`. La factorielle de `n` est noté comme `n!` -We can write a definition of factorial like this: +Nous pouvons écrire une définition de factorielle comme ceci: ```js n! = n * (n - 1) * (n - 2) * ...*1 ``` -Values of factorials for different `n`: +Valeurs des factorielles pour des `n` différents: ```js 1! = 1 @@ -22,10 +22,10 @@ Values of factorials for different `n`: 5! = 5 * 4 * 3 * 2 * 1 = 120 ``` -The task is to write a function `factorial(n)` that calculates `n!` using recursive calls. +La tâche est d'écrire une fonction `factorial(n)` qui calcule `n!` en utilisant des appels récursifs. ```js alert( factorial(5) ); // 120 ``` -P.S. Hint: `n!` can be written as `n * (n-1)!` For instance: `3! = 3*2! = 3*2*1! = 6` +P.S. Indice: `n!` peut être écrit `n * (n-1)!` Par exemple: `3! = 3*2! = 3*2*1! = 6` diff --git a/1-js/06-advanced-functions/01-recursion/03-fibonacci-numbers/solution.md b/1-js/06-advanced-functions/01-recursion/03-fibonacci-numbers/solution.md index 91bcecc05..1a91b5531 100644 --- a/1-js/06-advanced-functions/01-recursion/03-fibonacci-numbers/solution.md +++ b/1-js/06-advanced-functions/01-recursion/03-fibonacci-numbers/solution.md @@ -1,6 +1,6 @@ -The first solution we could try here is the recursive one. +La première solution que nous pourrions essayer ici est la solution récursive. -Fibonacci numbers are recursive by definition: +Les nombres de Fibonacci sont récursifs par définition: ```js run function fib(n) { @@ -9,14 +9,14 @@ function fib(n) { alert( fib(3) ); // 2 alert( fib(7) ); // 13 -// fib(77); // will be extremely slow! +// fib(77); // Sera extrêmement lent! ``` -...But for big values of `n` it's very slow. For instance, `fib(77)` may hang up the engine for some time eating all CPU resources. +...Mais pour les grandes valeurs de `n` c'est très lent. Par exemple, `fib(77)` peut bloquer le moteur pendant un certain temps en consommant toutes les ressources du processeur. -That's because the function makes too many subcalls. The same values are re-evaluated again and again. +C'est parce que la fonction crée trop de sous-appels. Les mêmes valeurs sont réévaluées encore et encore. -For instance, let's see a piece of calculations for `fib(5)`: +Par exemple, voyons un calcul pour `fib(5)`: ```js no-beautify ... @@ -25,68 +25,68 @@ fib(4) = fib(3) + fib(2) ... ``` -Here we can see that the value of `fib(3)` is needed for both `fib(5)` and `fib(4)`. So `fib(3)` will be called and evaluated two times completely independently. +Ici, nous pouvons voir que la valeur de `fib(3)` est nécessaire pour les deux `fib(5)` et `fib(4)`. Alors `fib(3)` sera appelé et évalué deux fois de manière totalement indépendante. -Here's the full recursion tree: +Voici l'arbre de récursion complet: -![fibonacci recursion tree](fibonacci-recursion-tree.png) +![arbre de récursion de fibonacci](fibonacci-recursion-tree.png) -We can clearly notice that `fib(3)` is evaluated two times and `fib(2)` is evaluated three times. The total amount of computations grows much faster than `n`, making it enormous even for `n=77`. +Nous pouvons clairement remarquer que `fib(3)` est évalué deux fois et `fib(2)` est évalué trois fois. La quantité totale de calculs augmente beaucoup plus vite que `n`, le rendant énorme même pour `n=77`. -We can optimize that by remembering already-evaluated values: if a value of say `fib(3)` is calculated once, then we can just reuse it in future computations. +Nous pouvons optimiser cela en nous rappelant les valeurs déjà évaluées: si une valeur de `fib(3)` est calculé une fois, alors nous pouvons simplement le réutiliser dans les calculs futurs. -Another variant would be to give up recursion and use a totally different loop-based algorithm. +Une autre variante consisterait à abandonner la récursion et à utiliser un algorithme totalement différent basé sur des boucles. -Instead of going from `n` down to lower values, we can make a loop that starts from `1` and `2`, then gets `fib(3)` as their sum, then `fib(4)` as the sum of two previous values, then `fib(5)` and goes up and up, till it gets to the needed value. On each step we only need to remember two previous values. +Au lieu de partir de `n` jusqu'à des valeurs plus basses, nous pouvons faire une boucle qui commence à partir de `1` et `2`, puis obtient `fib(3)` comme leur somme, ensuite `fib(4)` comme la somme de deux valeurs précédentes, ensuite `fib(5)` et monte, jusqu'à ce qu'il atteigne la valeur nécessaire. À chaque étape, il suffit de rappeler deux valeurs précédentes. -Here are the steps of the new algorithm in details. +Voici les étapes du nouvel algorithme en détails. -The start: +Le début: ```js -// a = fib(1), b = fib(2), these values are by definition 1 +// a = fib(1), b = fib(2), ces valeurs sont par définition 1 let a = 1, b = 1; -// get c = fib(3) as their sum +// obtien c = fib(3) comme leur somme let c = a + b; -/* we now have fib(1), fib(2), fib(3) +/* nous avons maintenant fib(1), fib(2), fib(3) a b c 1, 1, 2 */ ``` -Now we want to get `fib(4) = fib(2) + fib(3)`. +Maintenant, nous voulons obtenir `fib(4) = fib(2) + fib(3)`. -Let's shift the variables: `a,b` will get `fib(2),fib(3)`, and `c` will get their sum: +Passons aux variables: `a,b` aura `fib(2),fib(3)`, et `c` obtiendra leur somme: ```js no-beautify -a = b; // now a = fib(2) -b = c; // now b = fib(3) +a = b; // maintenant a = fib(2) +b = c; // maintenant b = fib(3) c = a + b; // c = fib(4) -/* now we have the sequence: +/* maintenant nous avons la séquence: a b c 1, 1, 2, 3 */ ``` -The next step gives another sequence number: +L'étape suivante donne un autre numéro de séquence: ```js no-beautify -a = b; // now a = fib(3) -b = c; // now b = fib(4) +a = b; // maintenant a = fib(3) +b = c; // maintenant b = fib(4) c = a + b; // c = fib(5) -/* now the sequence is (one more number): +/* maintenant la séquence est (encore un numéro): a b c 1, 1, 2, 3, 5 */ ``` -...And so on until we get the needed value. That's much faster than recursion and involves no duplicate computations. +...Et ainsi de suite jusqu'à l'obtention de la valeur nécessaire. C'est beaucoup plus rapide que la récursion et n'implique aucun calcul en double. -The full code: +Le code complet: ```js run function fib(n) { @@ -105,6 +105,6 @@ alert( fib(7) ); // 13 alert( fib(77) ); // 5527939700884757 ``` -The loop starts with `i=3`, because the first and the second sequence values are hard-coded into variables `a=1`, `b=1`. +La boucle commence par `i=3`, parce que les première et deuxième valeurs de séquence sont codées en dur dans des variables `a=1`, `b=1`. -The approach is called [dynamic programming bottom-up](https://en.wikipedia.org/wiki/Dynamic_programming). +Cette approche s'appelle la [programmation dynamique de bas en haut](https://fr.wikipedia.org/wiki/Programmation_dynamique). diff --git a/1-js/06-advanced-functions/01-recursion/03-fibonacci-numbers/task.md b/1-js/06-advanced-functions/01-recursion/03-fibonacci-numbers/task.md index 3cdadd219..527c0ffd5 100644 --- a/1-js/06-advanced-functions/01-recursion/03-fibonacci-numbers/task.md +++ b/1-js/06-advanced-functions/01-recursion/03-fibonacci-numbers/task.md @@ -2,24 +2,24 @@ importance: 5 --- -# Fibonacci numbers +# Numéros de Fibonacci -The sequence of [Fibonacci numbers](https://en.wikipedia.org/wiki/Fibonacci_number) has the formula Fn = Fn-1 + Fn-2. In other words, the next number is a sum of the two preceding ones. +La séquence des [Numéros de Fibonacci](https://fr.wikipedia.org/wiki/Nombre_de_Fibonacci) a la formule Fn = Fn-1 + Fn-2. En d'autres termes, le nombre suivant est la somme des deux précédents. -First two numbers are `1`, then `2(1+1)`, then `3(1+2)`, `5(2+3)` and so on: `1, 1, 2, 3, 5, 8, 13, 21...`. +Les deux premiers chiffres sont `1`, puis `2(1+1)`, ensuite `3(1+2)`, `5(2+3)` etc: `1, 1, 2, 3, 5, 8, 13, 21...`. -Fibonacci numbers are related to the [Golden ratio](https://en.wikipedia.org/wiki/Golden_ratio) and many natural phenomena around us. +Les nombres de Fibonacci sont liés au [nombre d'or](https://fr.wikipedia.org/wiki/Nombre_d%27or) et de nombreux phénomènes naturels autour de nous. -Write a function `fib(n)` that returns the `n-th` Fibonacci number. +Écrire une fonction `fib(n)` qui retourne le Numéro de Fibonacci `n-th`. -An example of work: +Un exemple de travail: ```js -function fib(n) { /* your code */ } +function fib(n) { /* votre code */ } alert(fib(3)); // 2 alert(fib(7)); // 13 alert(fib(77)); // 5527939700884757 ``` -P.S. The function should be fast. The call to `fib(77)` should take no more than a fraction of a second. +P.S. La fonction devrait être rapide. L'appel de `fib(77)` devrait prendre pas plus d'une fraction de seconde. diff --git a/1-js/06-advanced-functions/01-recursion/04-output-single-linked-list/solution.md b/1-js/06-advanced-functions/01-recursion/04-output-single-linked-list/solution.md index 4e9de1469..a33800e9b 100644 --- a/1-js/06-advanced-functions/01-recursion/04-output-single-linked-list/solution.md +++ b/1-js/06-advanced-functions/01-recursion/04-output-single-linked-list/solution.md @@ -1,6 +1,6 @@ -# Loop-based solution +# Solution basée sur la boucle -The loop-based variant of the solution: +La variante de la solution basée sur la boucle: ```js run let list = { @@ -30,7 +30,7 @@ function printList(list) { printList(list); ``` -Please note that we use a temporary variable `tmp` to walk over the list. Technically, we could use a function parameter `list` instead: +Veuillez noter que nous utilisons une variable temporaire `tmp` pour parcourir la liste. Techniquement, nous pourrions utiliser un paramètre de fonction `list` à la place: ```js function printList(list) { @@ -43,15 +43,15 @@ function printList(list) { } ``` -...But that would be unwise. In the future we may need to extend a function, do something else with the list. If we change `list`, then we loose such ability. +...Mais ce ne serait pas sage. Dans le futur, nous allons peut-être devoir étendre une fonction, faire autre chose avec la liste. Si nous changeons `list`, nous perdons cette capacité. -Talking about good variable names, `list` here is the list itself. The first element of it. And it should remain like that. That's clear and reliable. +Parlant des bons noms de variables, `list` est la liste elle-même. Le premier élément de celui-ci. Et ça devrait rester comme ça. C'est clair et fiable. -From the other side, the role of `tmp` is exclusively a list traversal, like `i` in the `for` loop. +De l’autre côté, le rôle de `tmp` est exclusivement une liste de traversée, comme `i` dans la boucle `for`. -# Recursive solution +# Solution récursive -The recursive variant of `printList(list)` follows a simple logic: to output a list we should output the current element `list`, then do the same for `list.next`: +La variante récursive de `printList(list)` suit une logique simple: pour afficher une liste, il faut afficher l'élément courant `list`, puis faire de même pour `list.next`: ```js run let list = { @@ -70,10 +70,10 @@ let list = { function printList(list) { - alert(list.value); // output the current item + alert(list.value); // affiche l'élément en cours if (list.next) { - printList(list.next); // do the same for the rest of the list + printList(list.next); // fait la même chose pour le reste de la liste } } @@ -81,8 +81,8 @@ function printList(list) { printList(list); ``` -Now what's better? +Maintenant qu'est-ce qui est le mieux? -Technically, the loop is more effective. These two variants do the same, but the loop does not spend resources for nested function calls. +Techniquement, la boucle est plus efficace. Ces deux variantes font la même chose, mais la boucle ne dépense pas de ressources pour les appels de fonction imbriqués. -From the other side, the recursive variant is shorter and sometimes easier to understand. +De l'autre côté, la variante récursive est plus courte et parfois plus facile à comprendre. diff --git a/1-js/06-advanced-functions/01-recursion/04-output-single-linked-list/task.md b/1-js/06-advanced-functions/01-recursion/04-output-single-linked-list/task.md index 1076b952a..d8036ae68 100644 --- a/1-js/06-advanced-functions/01-recursion/04-output-single-linked-list/task.md +++ b/1-js/06-advanced-functions/01-recursion/04-output-single-linked-list/task.md @@ -2,9 +2,9 @@ importance: 5 --- -# Output a single-linked list +# Produire une liste de simple lien -Let's say we have a single-linked list (as described in the chapter ): +Disons que nous avons une liste de simple lien (comme décrit dans le chapitre ): ```js let list = { @@ -22,8 +22,8 @@ let list = { }; ``` -Write a function `printList(list)` that outputs list items one-by-one. +Écrire une fonction `printList(list)` qui sort les éléments de la liste un par un. -Make two variants of the solution: using a loop and using recursion. +Faites deux variantes de la solution: en utilisant une boucle et en utilisant la récursion. -What's better: with recursion or without it? +Qu'est-ce qui est le mieux: Avec ou sans récursion ? diff --git a/1-js/06-advanced-functions/01-recursion/05-output-single-linked-list-reverse/solution.md b/1-js/06-advanced-functions/01-recursion/05-output-single-linked-list-reverse/solution.md index 4357ff208..fe59dafe4 100644 --- a/1-js/06-advanced-functions/01-recursion/05-output-single-linked-list-reverse/solution.md +++ b/1-js/06-advanced-functions/01-recursion/05-output-single-linked-list-reverse/solution.md @@ -1,8 +1,8 @@ -# Using a recursion +# Utiliser une récursion -The recursive logic is a little bit tricky here. +La logique récursive est un peu délicate ici. -We need to first output the rest of the list and *then* output the current one: +Nous devons d'abord afficher le reste de la liste et *ensuite* afficher l'actuel: ```js run let list = { @@ -31,13 +31,13 @@ function printReverseList(list) { printReverseList(list); ``` -# Using a loop +# En utilisant une boucle -The loop variant is also a little bit more complicated then the direct output. +La variante de boucle est aussi un peu plus compliquée que la sortie directe. -There is no way to get the last value in our `list`. We also can't "go back". +Il n'y a aucun moyen d'obtenir la dernière valeur de notre `list`. Nous ne pouvons pas non plus "revenir en arrière". -So what we can do is to first go through the items in the direct order and remember them in an array, and then output what we remembered in the reverse order: +Nous pouvons donc commencer par parcourir les éléments dans l'ordre direct et les mémoriser dans un tableau, puis afficher ce que nous nous sommes rappelés dans l'ordre inverse: ```js run let list = { @@ -71,4 +71,4 @@ function printReverseList(list) { printReverseList(list); ``` -Please note that the recursive solution actually does exactly the same: it follows the list, remembers the items in the chain of nested calls (in the execution context stack), and then outputs them. +Veuillez noter que la solution récursive fait exactement la même chose: elle suit la liste, mémorise les éléments de la chaîne d'appels imbriqués (dans la pile de contexte d'exécution), puis les affiches. diff --git a/1-js/06-advanced-functions/01-recursion/05-output-single-linked-list-reverse/task.md b/1-js/06-advanced-functions/01-recursion/05-output-single-linked-list-reverse/task.md index 81b1f3e33..71e67e5f1 100644 --- a/1-js/06-advanced-functions/01-recursion/05-output-single-linked-list-reverse/task.md +++ b/1-js/06-advanced-functions/01-recursion/05-output-single-linked-list-reverse/task.md @@ -2,8 +2,8 @@ importance: 5 --- -# Output a single-linked list in the reverse order +# Afficher une liste à lien unique dans l'ordre inverse -Output a single-linked list from the previous task in the reverse order. +Afficher une liste à lien unique de la tâche précédente dans l'ordre inverse. -Make two solutions: using a loop and using a recursion. +Faites deux solutions: en utilisant une boucle et en utilisant une récursion. diff --git a/1-js/06-advanced-functions/01-recursion/article.md b/1-js/06-advanced-functions/01-recursion/article.md index 214de18c2..62540c63d 100644 --- a/1-js/06-advanced-functions/01-recursion/article.md +++ b/1-js/06-advanced-functions/01-recursion/article.md @@ -1,18 +1,18 @@ -# Recursion and stack +# Récursion et pile -Let's return to functions and study them more in-depth. +Revenons aux fonctions et étudions-les plus en profondeur. -Our first topic will be *recursion*. +Notre premier sujet sera la *recursion*. -If you are not new to programming, then it is probably familiar and you could skip this chapter. +Si vous n’êtes pas novice en programmation, cela vous est probablement familier et vous pouvez sauter ce chapitre. -Recursion is a programming pattern that is useful in situations when a task can be naturally split into several tasks of the same kind, but simpler. Or when a task can be simplified into an easy action plus a simpler variant of the same task. Or, as we'll see soon, to deal with certain data structures. +La récursion est un modèle de programmation utile dans les situations où une tâche peut être naturellement divisée en plusieurs tâches du même type, mais plus simple. Ou lorsqu'une tâche peut être simplifiée en une action facile plus une variante plus simple de la même tâche. Ou, comme nous le verrons bientôt, pour traiter certaines structures de données. -When a function solves a task, in the process it can call many other functions. A partial case of this is when a function calls *itself*. That's called *recursion*. +Lorsqu'une fonction résout une tâche, elle peut appeler de nombreuses autres fonctions. Cela se produit partiellement lorsqu'une fonction s'appelle *elle-même*. Cela s'appelle la *récursion*. -## Two ways of thinking +## Deux façons de penser -For something simple to start with -- let's write a function `pow(x, n)` that raises `x` to a natural power of `n`. In other words, multiplies `x` by itself `n` times. +Prenons quelque chose de simple pour commencer -- écrivons une fonction `pow(x, n)` qui élève `x` à une puissance naturel de `n`. En d'autres termes, multiplie `x` par lui-même `n` fois. ```js pow(2, 2) = 4 @@ -20,15 +20,15 @@ pow(2, 3) = 8 pow(2, 4) = 16 ``` -There are two ways to implement it. +Il y a deux façons de le mettre en œuvre. -1. Iterative thinking: the `for` loop: +1. La pensée itérative: la boucle `for`: ```js run function pow(x, n) { let result = 1; - // multiply result by x n times in the loop + // multiplier le résultat par x n fois dans la boucle for (let i = 0; i < n; i++) { result *= x; } @@ -39,7 +39,7 @@ There are two ways to implement it. alert( pow(2, 3) ); // 8 ``` -2. Recursive thinking: simplify the task and call self: +2. La pensée récursive: simplifie la tâche et s'appele elle-même: ```js run function pow(x, n) { @@ -53,9 +53,9 @@ There are two ways to implement it. alert( pow(2, 3) ); // 8 ``` -Please note how the recursive variant is fundamentally different. +Veuillez noter en quoi la variante récursive est fondamentalement différente. -When `pow(x, n)` is called, the execution splits into two branches: +Quand `pow(x, n)` est appelé, l'exécution se scinde en deux branches: ```js if n==1 = x @@ -65,27 +65,27 @@ pow(x, n) = else = x * pow(x, n - 1) ``` -1. If `n == 1`, then everything is trivial. It is called *the base* of recursion, because it immediately produces the obvious result: `pow(x, 1)` equals `x`. -2. Otherwise, we can represent `pow(x, n)` as `x * pow(x, n - 1)`. In maths, one would write xn = x * xn-1. This is called *a recursive step*: we transform the task into a simpler action (multiplication by `x`) and a simpler call of the same task (`pow` with lower `n`). Next steps simplify it further and further until `n` reaches `1`. +1. Si `n == 1`, alors tout est trivial. On l'appelle *la base* de la récursion, car elle produit immédiatement le résultat évident: `pow(x, 1)` équivaut à `x`. +2. Sinon, nous pouvons représenter `pow(x, n)` comme `x * pow(x, n - 1)`. En maths, on écrirait xn = x * xn-1. Ceci s'appelle *une étape récursive*: nous transformons la tâche en une action plus simple (multiplication par `x`) et un appel plus simple de la même tâche (`pow` avec le petit `n`). Les prochaines étapes le simplifient de plus en plus jusqu’à ce que `n` atteigne `1`. -We can also say that `pow` *recursively calls itself* till `n == 1`. +On peut aussi dire que `pow` *s'appelle récursivement* jusqu'à ce que `n == 1`. -![recursive diagram of pow](recursion-pow.png) +![diagramme récursif de puissance](recursion-pow.png) -For example, to calculate `pow(2, 4)` the recursive variant does these steps: +Par exemple, pour calculer `pow(2, 4)` la variante récursive effectue ces étapes: 1. `pow(2, 4) = 2 * pow(2, 3)` 2. `pow(2, 3) = 2 * pow(2, 2)` 3. `pow(2, 2) = 2 * pow(2, 1)` 4. `pow(2, 1) = 2` -So, the recursion reduces a function call to a simpler one, and then -- to even more simpler, and so on, until the result becomes obvious. +Ainsi, la récursion réduit un appel de fonction à un processus plus simple, puis -- à un processus encore plus simple, etc. jusqu'à ce que le résultat devienne évident. -````smart header="Recursion is usually shorter" -A recursive solution is usually shorter than an iterative one. +````smart header="La récursion est généralement plus courte" +Une solution récursive est généralement plus courte qu'une solution itérative. -Here we can rewrite the same using the conditional operator `?` instead of `if` to make `pow(x, n)` more terse and still very readable: +Ici, nous pouvons réécrire la même chose en utilisant l'opérateur conditionnel `?` Au lieu de `if` pour rendre `pow (x, n)` plus concis et toujours très lisible: ```js run function pow(x, n) { @@ -94,36 +94,36 @@ function pow(x, n) { ``` ```` -The maximal number of nested calls (including the first one) is called *recursion depth*. In our case, it will be exactly `n`. +Le nombre maximal d'appels imbriqués (y compris le premier) est appelé la *profondeur de récursivité*. Dans notre cas, ce sera exactement `n`. -The maximal recursion depth is limited by JavaScript engine. We can make sure about 10000, some engines allow more, but 100000 is probably out of limit for the majority of them. There are automatic optimizations that help alleviate this ("tail calls optimizations"), but they are not yet supported everywhere and work only in simple cases. +La profondeur maximale de récursion est limitée par le moteur JavaScript. Nous sommes sur qu'il va jusqu'à 10000, certains moteurs en autorisent plus, mais 100000 est probablement hors limite pour la majorité d'entre eux. Il existe des optimisations automatiques qui aident à atténuer ce problème ("optimisations d'appels en aval"), mais elles ne sont pas encore prises en charge partout et ne fonctionnent que dans des cas simples. -That limits the application of recursion, but it still remains very wide. There are many tasks where recursive way of thinking gives simpler code, easier to maintain. +Cela limite l'application de la récursion, mais cela reste très large. Il y a beaucoup de tâches pour lesquelles la pensée récursive donne un code plus simple et plus facile à gérer. -## The execution context and stack +## Le contexte d'exécution et la pile -Now let's examine how recursive calls work. For that we'll look under the hood of functions. +Voyons maintenant comment fonctionnent les appels récursifs. Pour cela, nous allons regarder sous le capot des fonctions. -The information about the process of execution of a running function is stored in its *execution context*. +Les informations sur le processus d'exécution d'une fonction en cours d'exécution sont stockées dans son *contexte d'exécution*. -The [execution context](https://tc39.github.io/ecma262/#sec-execution-contexts) is an internal data structure that contains details about the execution of a function: where the control flow is now, the current variables, the value of `this` (we don't use it here) and few other internal details. +Le [contexte d'exécution](https://tc39.github.io/ecma262/#sec-execution-contexts) est une structure de données interne contenant des détails sur l'exécution d'une fonction: où le flux de contrôle est maintenant, les variables actuelles, la valeur de `this` (nous ne l'utilisons pas ici) et quelques autres détails internes. -One function call has exactly one execution context associated with it. +Un appel de fonction est associé à exactement un contexte d'exécution. -When a function makes a nested call, the following happens: +Lorsqu'une fonction effectue un appel imbriqué, les événements suivants se produisent: -- The current function is paused. -- The execution context associated with it is remembered in a special data structure called *execution context stack*. -- The nested call executes. -- After it ends, the old execution context is retrieved from the stack, and the outer function is resumed from where it stopped. +- La fonction en cours est suspendue. +- Le contexte d’exécution qui lui est associé est mémorisé dans une structure de données spéciale appelée *pile de contexte d’exécution*. +- L'appel imbriqué s'exécute. +- Une fois terminé, l'ancien contexte d'exécution est extrait de la pile et la fonction externe reprend à partir de son point d'arrêt. -Let's see what happens during the `pow(2, 3)` call. +Voyons ce qui se passe pendant l'appel de `pow(2, 3)`. ### pow(2, 3) -In the beginning of the call `pow(2, 3)` the execution context will store variables: `x = 2, n = 3`, the execution flow is at line `1` of the function. +Au début de l'appel de `pow(2, 3)` le contexte d'exécution stockera des variables: `x = 2, n = 3`, le flux d'exécution est à la ligne `1` de la fonction. -We can sketch it as: +Nous pouvons l'esquisser comme:
  • @@ -132,7 +132,7 @@ We can sketch it as:
-That's when the function starts to execute. The condition `n == 1` is false, so the flow continues into the second branch of `if`: +C'est à ce moment que la fonction commence à s'exécuter. La condition`n == 1` est faux, donc le flux continue dans la deuxième branche de `if`: ```js run function pow(x, n) { @@ -149,7 +149,7 @@ alert( pow(2, 3) ); ``` -The variables are same, but the line changes, so the context is now: +Les variables sont les mêmes, mais la ligne change, le contexte est donc le suivant:
  • @@ -158,19 +158,19 @@ The variables are same, but the line changes, so the context is now:
-To calculate `x * pow(x, n - 1)`, we need to make a subcall of `pow` with new arguments `pow(2, 2)`. +Pour calculer `x * pow(x, n - 1)`, nous devons faire un sous-appel de `pow` avec de nouveaux arguments `pow(2, 2)`. ### pow(2, 2) -To do a nested call, JavaScript remembers the current execution context in the *execution context stack*. +Pour effectuer un appel imbriqué, JavaScript se souvient du contexte d'exécution actuel dans le *contexte d'exécution de la pile*. -Here we call the same function `pow`, but it absolutely doesn't matter. The process is the same for all functions: +Ici, nous appelons la même fonction `pow`, mais cela n’a absolument aucune importance. Le processus est le même pour toutes les fonctions: -1. The current context is "remembered" on top of the stack. -2. The new context is created for the subcall. -3. When the subcall is finished -- the previous context is popped from the stack, and its execution continues. +1. Le contexte actuel est "mémorisé" en haut de la pile. +2. Le nouveau contexte est créé pour le sous-appel. +3. Quand le sous-appel est fini -- le contexte précédent est extrait de la pile et son exécution se poursuit. -Here's the context stack when we entered the subcall `pow(2, 2)`: +Voici la pile de contexte lorsque nous sommes entrés dans le sous-appel `pow(2, 2)`:
  • @@ -183,15 +183,15 @@ Here's the context stack when we entered the subcall `pow(2, 2)`:
-The new current execution context is on top (and bold), and previous remembered contexts are below. +Le nouveau contexte d'exécution actuel est en haut (et en gras) et les contextes précédemment mémorisés sont en dessous. -When we finish the subcall -- it is easy to resume the previous context, because it keeps both variables and the exact place of the code where it stopped. Here in the picture we use the word "line", but of course it's more precise. +Quand on termine le sous-appel -- il est facile de reprendre le contexte précédent, car il conserve les deux variables et l'emplacement exact du code où il s'est arrêté. Ici, sur la photo, nous utilisons le mot "line", mais bien sûr, il est plus précis. ### pow(2, 1) -The process repeats: a new subcall is made at line `5`, now with arguments `x=2`, `n=1`. +Le processus se répète: un nouveau sous-appel est fait à la ligne `5`, maintenant avec des arguments `x=2`, `n=1`. -A new execution context is created, the previous one is pushed on top of the stack: +Un nouveau contexte d'exécution est créé, le précédent est placé en haut de la pile:
  • @@ -208,11 +208,11 @@ A new execution context is created, the previous one is pushed on top of the sta
-There are 2 old contexts now and 1 currently running for `pow(2, 1)`. +Il y a 2 anciens contextes et 1 en cours d'exécution pour `pow(2, 1)`. -### The exit +### La sortie -During the execution of `pow(2, 1)`, unlike before, the condition `n == 1` is truthy, so the first branch of `if` works: +Pendant l'exécution de `pow(2, 1)`, contrairement à avant, la condition `n == 1` est la vérité, donc la première branche de `if` fonctionne: ```js function pow(x, n) { @@ -226,9 +226,9 @@ function pow(x, n) { } ``` -There are no more nested calls, so the function finishes, returning `2`. +Il n'y a plus d'appels imbriqués, donc la fonction se termine en renvoyant`2`. -As the function finishes, its execution context is not needed anymore, so it's removed from the memory. The previous one is restored off the top of the stack: +Lorsque la fonction se termine, son contexte d'exécution n'est plus nécessaire, il est donc supprimé de la mémoire. La précédente est restaurée en haut de la pile:
    @@ -242,9 +242,9 @@ As the function finishes, its execution context is not needed anymore, so it's r
-The execution of `pow(2, 2)` is resumed. It has the result of the subcall `pow(2, 1)`, so it also can finish the evaluation of `x * pow(x, n - 1)`, returning `4`. +L'exécution de `pow(2, 2)` est repris. Il a le résultat du sous-appel `pow(2, 1)`, de sorte qu'il peut également terminer l'évaluation de `x * pow(x, n - 1)`, retournant `4`. -Then the previous context is restored: +Ensuite, le contexte précédent est restauré:
  • @@ -253,15 +253,15 @@ Then the previous context is restored:
-When it finishes, we have a result of `pow(2, 3) = 8`. +Quand il se termine, nous avons un résultat de `pow(2, 3) = 8`. -The recursion depth in this case was: **3**. +La profondeur de récursion dans ce cas était: **3**. -As we can see from the illustrations above, recursion depth equals the maximal number of context in the stack. +Comme nous pouvons le voir dans les illustrations ci-dessus, la profondeur de récursion est égale au nombre maximal de contextes dans la pile. -Note the memory requirements. Contexts take memory. In our case, raising to the power of `n` actually requires the memory for `n` contexts, for all lower values of `n`. +Notez les besoins en mémoire. Les contextes prennent de la mémoire. Dans notre cas, augmenter à la puissance de `n` nécessite en réalité de la mémoire pour les contextes `n`, pour toutes les valeurs inférieures de `n`. -A loop-based algorithm is more memory-saving: +Un algorithme basé sur des boucles est plus économe en mémoire: ```js function pow(x, n) { @@ -275,19 +275,19 @@ function pow(x, n) { } ``` -The iterative `pow` uses a single context changing `i` and `result` in the process. Its memory requirements are small, fixed and do not depend on `n`. +Le `pow` itératif utilise un contexte unique qui change les processus `i` et `result` dans le processus. Ses besoins en mémoire sont faibles, fixes et ne dépendent pas de `n`. -**Any recursion can be rewritten as a loop. The loop variant usually can be made more effective.** +**Toute récursion peut être réécrite sous forme de boucle. La variante de boucle peut généralement être rendue plus efficace.** -...But sometimes the rewrite is non-trivial, especially when function uses different recursive subcalls depending on conditions and merges their results or when the branching is more intricate. And the optimization may be unneeded and totally not worth the efforts. +..Parfois, la réécriture n’est pas triviale, en particulier lorsque la fonction utilise différents sous-appels récursifs en fonction des conditions et fusionne leurs résultats ou lorsque la création de branche est plus complexe. Et l'optimisation risque de ne pas être nécessaire et de ne pas valoir la peine. -Recursion can give a shorter code, easier to understand and support. Optimizations are not required in every place, mostly we need a good code, that's why it's used. +La récursion peut donner un code plus court, plus facile à comprendre et à supporter. Les optimisations ne sont pas nécessaires à chaque endroit, nous avons surtout besoin d'un bon code, c'est pourquoi il est utilisé. -## Recursive traversals +## Traversées récursives -Another great application of the recursion is a recursive traversal. +Une autre grande application de la récursion est une traversée récursive. -Imagine, we have a company. The staff structure can be presented as an object: +Imaginez, nous avons une entreprise. La structure du personnel peut être présentée comme un objet: ```js let company = { @@ -316,34 +316,34 @@ let company = { }; ``` -In other words, a company has departments. +En d'autres termes, une entreprise a des départements. -- A department may have an array of staff. For instance, `sales` department has 2 employees: John and Alice. -- Or a department may split into subdepartments, like `development` has two branches: `sites` and `internals`. Each of them has their own staff. -- It is also possible that when a subdepartment grows, it divides into subsubdepartments (or teams). +- Un département peut avoir un tableau de personnel. Par exemple, le département des ventes compte 2 employés: John et Alice. +- Ou bien un département peut être divisé en sous-départements, comme `development` a deux branches: `sites` et `internes`. Chacun d'entre eux a son propre personnel. +- Il est également possible que lorsqu'un sous-département s'agrandisse, il se divise en sous-départements (ou équipes). - For instance, the `sites` department in the future may be split into teams for `siteA` and `siteB`. And they, potentially, can split even more. That's not on the picture, just something to have in mind. + Par exemple, le département `sites` peut être divisé en équipes pour les sites `siteA` et `siteB`. Et, potentiellement, ils peuvent être diviser encore plus. Ce n'est pas sur la photo, c'est juste quelque chose qu'ont pourrait immaginer. -Now let's say we want a function to get the sum of all salaries. How can we do that? +Maintenant, disons que nous voulons une fonction pour obtenir la somme de tous les salaires. Comment peut-on faire ça? -An iterative approach is not easy, because the structure is not simple. The first idea may be to make a `for` loop over `company` with nested subloop over 1st level departments. But then we need more nested subloops to iterate over the staff in 2nd level departments like `sites`. ...And then another subloop inside those for 3rd level departments that might appear in the future? Should we stop on level 3 or make 4 levels of loops? If we put 3-4 nested subloops in the code to traverse a single object, it becomes rather ugly. +Une approche itérative n’est pas facile, car la structure n’est pas simple. La première idée peut être de créer une boucle `for` sur company avec une sous-boucle imbriqué sur les départements de premier niveau. Mais ensuite, nous avons besoin de plus de sous-cadres imbriqués pour parcourir le personnel des départements de second niveau, tels que les `sites`. ... Et puis une autre sous-boucle dans ceux des départements de 3ème niveau qui pourraient apparaître dans le futur? Faut-il s'arrêter au niveau 3 ou faire 4 niveaux de boucles? Si nous mettons 3-4 sous-boucles imbriqués dans le code pour traverser un seul objet, cela devient plutôt moche. -Let's try recursion. +Essayons la récursion. -As we can see, when our function gets a department to sum, there are two possible cases: +Comme nous pouvons le constater, lorsque notre fonction demande à un département de faire la somme, il existe deux cas possibles: -1. Either it's a "simple" department with an *array of people* -- then we can sum the salaries in a simple loop. -2. Or it's *an object with `N` subdepartments* -- then we can make `N` recursive calls to get the sum for each of the subdeps and combine the results. +1. S’il s’agit d’un "simple" département avec un *éventail de personnes*, nous pouvons alors additionner les salaires en une simple boucle. +2. Ou bien *c'est un objet avec `N` sous-départements * -- alors nous pouvons faire des appels` N` récursifs pour obtenir la somme de chaque sous-étape et combiner les résultats. -The (1) is the base of recursion, the trivial case. +Le (1) est la base de la récursion, le cas trivial. -The (2) is the recursive step. A complex task is split into subtasks for smaller departments. They may in turn split again, but sooner or later the split will finish at (1). +Le (2) est l'étape récursive. Une tâche complexe est divisée en sous-tâches pour les plus petits départements. Ils peuvent à leur tour se séparer à nouveau, mais tôt ou tard, la séparation se terminera en (1). -The algorithm is probably even easier to read from the code: +L'algorithme est probablement encore plus facile à lire à partir du code: ```js run -let company = { // the same object, compressed for brevity +let company = { // le même objet, compressé pour la brièveté sales: [{name: 'John', salary: 1000}, {name: 'Alice', salary: 600 }], development: { sites: [{name: 'Peter', salary: 2000}, {name: 'Alex', salary: 1800 }], @@ -351,15 +351,15 @@ let company = { // the same object, compressed for brevity } }; -// The function to do the job +// La fonction pour faire le travail *!* function sumSalaries(department) { if (Array.isArray(department)) { // case (1) - return department.reduce((prev, current) => prev + current.salary, 0); // sum the array + return department.reduce((prev, current) => prev + current.salary, 0); // additionne le tableau } else { // case (2) let sum = 0; for (let subdep of Object.values(department)) { - sum += sumSalaries(subdep); // recursively call for subdepartments, sum the results + sum += sumSalaries(subdep); // appel récursivement pour les sous-départements, additionnez les résultats } return sum; } @@ -369,62 +369,62 @@ function sumSalaries(department) { alert(sumSalaries(company)); // 6700 ``` -The code is short and easy to understand (hopefully?). That's the power of recursion. It also works for any level of subdepartment nesting. +Le code est court et facile à comprendre (tout va bien?). C'est le pouvoir de la récursion. Cela fonctionne également pour tous les niveaux d'imbrication de sous-départements. -Here's the diagram of calls: +Voici le schéma des appels: -![recursive salaries](recursive-salaries.png) +![salaires récursifs](recursive-salaries.png) -We can easily see the principle: for an object `{...}` subcalls are made, while arrays `[...]` are the "leaves" of the recursion tree, they give immediate result. +On peut facilement voir le principe: pour un objet `{...}` les sous-appels sont faits, alors que les tableaux `[...]` sont les "feuilles" de l'arbre de récurrence, elles donnent un résultat immédiat. -Note that the code uses smart features that we've covered before: +Notez que le code utilise des fonctionnalités intelligentes que nous avons déjà abordées: -- Method `arr.reduce` explained in the chapter to get the sum of the array. -- Loop `for(val of Object.values(obj))` to iterate over object values: `Object.values` returns an array of them. +- La méthode `arr.reduce` a été expliquée dans le chapitre pour obtenir la somme du tableau. +- La boucle `for(val of Object.values(obj))` itérer sur les valeurs d'objet: `Object.values` retourne un tableau d'eux-mêmes. -## Recursive structures +## Structures récursives -A recursive (recursively-defined) data structure is a structure that replicates itself in parts. +Une structure de données récursive (définie de manière récursive) est une structure qui se réplique par parties. -We've just seen it in the example of a company structure above. +Nous venons de le voir dans l'exemple d'une structure d'entreprise ci-dessus. -A company *department* is: -- Either an array of people. -- Or an object with *departments*. +Un *département* d'entreprise est: +- Soit un éventail de personnes. +- Ou un objet avec des *départements*. -For web-developers there are much better-known examples: HTML and XML documents. +Pour les développeurs Web, il existe des exemples bien mieux connus: les documents HTML et XML. -In the HTML document, an *HTML-tag* may contain a list of: -- Text pieces. -- HTML-comments. -- Other *HTML-tags* (that in turn may contain text pieces/comments or other tags etc). +Dans le document HTML, une balise *HTML* peut contenir une liste de: +- Morceaux de texte. +- Commentaires HTML. +- Autres *balises HTML* (pouvant à leur tour contenir des morceaux de texte/commentaires ou d’autres balises, etc.). -That's once again a recursive definition. +C'est encore une définition récursive. -For better understanding, we'll cover one more recursive structure named "Linked list" that might be a better alternative for arrays in some cases. +Pour une meilleure compréhension, nous allons couvrir une autre structure récursive nommée "Liste chaînée" qui pourrait être une meilleure alternative aux tableaux dans certains cas. -### Linked list +### Liste chaînée -Imagine, we want to store an ordered list of objects. +Imaginez, nous voulons stocker une liste ordonnée d'objets. -The natural choice would be an array: +Le choix naturel serait un tableau: ```js let arr = [obj1, obj2, obj3]; ``` -...But there's a problem with arrays. The "delete element" and "insert element" operations are expensive. For instance, `arr.unshift(obj)` operation has to renumber all elements to make room for a new `obj`, and if the array is big, it takes time. Same with `arr.shift()`. +... Mais il y a un problème avec les tableaux. Les opérations "delete element" et "insert element" sont coûteuses. Par exemple, l'opération `arr.unshift(obj)` doit renuméroter tous les éléments pour faire de la place pour un nouvel `obj`, et si le tableau est grand, cela prend du temps. Même chose avec `arr.shift()`. -The only structural modifications that do not require mass-renumbering are those that operate with the end of array: `arr.push/pop`. So an array can be quite slow for big queues, when we have to work with the beginning. +Les seules modifications structurelles ne nécessitant pas de renumérotation en masse sont celles qui fonctionnent avec la fin du tableau: `arr.push/pop`. Ainsi, un tableau peut être assez lent pour les grandes files d'attente, lorsque nous devons travailler avec sont début. -Alternatively, if we really need fast insertion/deletion, we can choose another data structure called a [linked list](https://en.wikipedia.org/wiki/Linked_list). +Alternativement, si nous avons vraiment besoin d'une insertion/suppression rapide, nous pouvons choisir une autre structure de données appelée la [Liste chaînée](https://fr.wikipedia.org/wiki/Liste_cha%C3%AEn%C3%A9e). -The *linked list element* is recursively defined as an object with: +*L'élémentde la liste liée* est défini de manière récursive en tant qu'objet avec: - `value`. -- `next` property referencing the next *linked list element* or `null` if that's the end. +- `next` propriété référençant le prochain *élément de liste liée* ou `null` si c'est la fin. -For instance: +Par exemple: ```js let list = { @@ -442,9 +442,9 @@ let list = { }; ``` -Graphical representation of the list: +Représentation graphique de la liste: -![linked list](linked-list.png) +![Liste chaînée](linked-list.png) An alternative code for creation: @@ -455,26 +455,26 @@ list.next.next = { value: 3 }; list.next.next.next = { value: 4 }; ``` -Here we can even more clearer see that there are multiple objects, each one has the `value` and `next` pointing to the neighbour. The `list` variable is the first object in the chain, so following `next` pointers from it we can reach any element. +Ici, nous pouvons voir encore plus clairement qu'il y a plusieurs objets, chacun ayant les valeurs `value` et` next` pointant vers le voisin. La variable `list` est le premier objet de la chaîne. Par conséquent, en suivant les pointeurs `next`, nous pouvons atteindre n'importe quel élément. -The list can be easily split into multiple parts and later joined back: +La liste peut être facilement divisée en plusieurs parties et ultérieurement réunie: ```js let secondList = list.next.next; list.next.next = null; ``` -![linked list split](linked-list-split.png) +![séparation de la liste chaînée](linked-list-split.png) -To join: +Pour joindre: ```js list.next.next = secondList; ``` -And surely we can insert or remove items in any place. +Et nous pouvons sûrement insérer ou retirer des objets n’importe où. -For instance, to prepend a new value, we need to update the head of the list: +Par exemple, pour ajouter une nouvelle valeur, nous devons mettre à jour la tête de la liste: ```js let list = { value: 1 }; @@ -483,53 +483,54 @@ list.next.next = { value: 3 }; list.next.next.next = { value: 4 }; *!* -// prepend the new value to the list +// ajoute la nouvelle valeur à la liste list = { value: "new item", next: list }; */!* ``` -![linked list](linked-list-0.png) +![Liste chaînée](linked-list-0.png) -To remove a value from the middle, change `next` of the previous one: +Pour supprimer une valeur du milieu, changez le `next` de la précédente: ```js list.next = list.next.next; ``` -![linked list](linked-list-remove-1.png) +![Liste chaînée](linked-list-remove-1.png) -We made `list.next` jump over `1` to value `2`. The value `1` is now excluded from the chain. If it's not stored anywhere else, it will be automatically removed from the memory. +`List.next` a sauté `1` à la valeur `2`. La valeur `1` est maintenant exclue de la chaîne. Si elle n'est pas stocké ailleurs, elle sera automatiquement supprimé de la mémoire. -Unlike arrays, there's no mass-renumbering, we can easily rearrange elements. +Contrairement aux tableaux, il n'y a pas de renumérotation en masse, nous pouvons facilement réorganiser les éléments. -Naturally, lists are not always better than arrays. Otherwise everyone would use only lists. +Naturellement, les listes ne sont pas toujours meilleures que les tableaux. Sinon, tout le monde n'utiliserait que des listes. -The main drawback is that we can't easily access an element by its number. In an array that's easy: `arr[n]` is a direct reference. But in the list we need to start from the first item and go `next` `N` times to get the Nth element. +Le principal inconvénient est que nous ne pouvons pas facilement accéder à un élément par son numéro. Dans un tableau simple: `arr [n]` est une référence directe. Mais dans la liste, nous devons commencer à partir du premier élément et aller `next``N` fois pour obtenir le Nième élément. -...But we don't always need such operations. For instance, when we need a queue or even a [deque](https://en.wikipedia.org/wiki/Double-ended_queue) -- the ordered structure that must allow very fast adding/removing elements from both ends, but access to its middle is not needed. +...Mais nous n’avons pas toujours besoin de telles opérations. Par exemple, quand on a besoin d’une file d’attente ou même d’un [deque](https://en.wikipedia.org/wiki/Double-ended_queue) -- la structure ordonnée qui doit permettre l'ajout/suppression très rapide d'éléments des deux extrémités, mais l'accès au milieu n'est pas nécessaire. -Lists can be enhanced: -- We can add property `prev` in addition to `next` to reference the previous element, to move back easily. -- We can also add a variable named `tail` referencing the last element of the list (and update it when adding/removing elements from the end). -- ...The data structure may vary according to our needs. -## Summary +Les listes peuvent être améliorées: +- Nous pouvons ajouter la propriété `prev` en plus de `next` pour référencer l'élément précédent, pour revenir facilement. +- Nous pouvons également ajouter une variable nommée `tail` faisant référence au dernier élément de la liste (et la mettre à jour lors de l'ajout/suppression d'éléments de la fin). +- ... La structure de données peut varier en fonction de nos besoins. + +## Résumé Terms: -- *Recursion* is a programming term that means calling a function from itself. Recursive functions can be used to solve tasks in elegant ways. +- *Recursion* est un terme de programmation qui signifie q'une fonction s'appelle elle-même. Les fonctions récursives peuvent être utilisées pour résoudre des tâches de manière élégante. - When a function calls itself, that's called a *recursion step*. The *basis* of recursion is function arguments that make the task so simple that the function does not make further calls. +Lorsqu'une fonction s'appelle elle-même, cela s'appelle une *étape de récursion*. La *base* de la récursion est constituée par les arguments de la fonction qui rendent la tâche si simple que la fonction ne fait plus d'appels. -- A [recursively-defined](https://en.wikipedia.org/wiki/Recursive_data_type) data structure is a data structure that can be defined using itself. +- Une structure de données de [Type récursif](https://fr.wikipedia.org/wiki/Type_r%C3%A9cursif) est une structure de données qui peut être définie à l'aide de elle-même. - For instance, the linked list can be defined as a data structure consisting of an object referencing a list (or null). + Par exemple, la liste chaînée peut être définie comme une structure de données consistant en un objet référençant une liste (ou null). ```js list = { value, next -> list } ``` - Trees like HTML elements tree or the department tree from this chapter are also naturally recursive: they branch and every branch can have other branches. + Les arbres tels que l’arbre des éléments HTML ou l’arbre des départements de ce chapitre sont également naturellement récursifs: ils ont des branchent et chaque branche peut avoir d’autres branches. - Recursive functions can be used to walk them as we've seen in the `sumSalary` example. + Des fonctions récursives peuvent être utilisées pour les parcourir, comme nous l'avons vu dans l'exemple `sumSalary`. -Any recursive function can be rewritten into an iterative one. And that's sometimes required to optimize stuff. But for many tasks a recursive solution is fast enough and easier to write and support. +Toute fonction récursive peut être réécrite en une fonction itérative. Et c'est parfois nécessaire pour optimiser les choses. Mais pour de nombreuses tâches, une solution récursive est assez rapide et plus facile à écrire et à supporter.