递归算法_递归递归

递归算法

什么是递归? 递归是一个自我调用的函数。 (What is recursion? Recursion is a function that calls itself.)

We’re used to functions calling other functions. In the case of recursion, instead of a different function, we call the same one. So why is recursion so tricky to understand?

我们习惯于调用其他函数的函数。 在递归的情况下,我们调用相同的函数,而不是不同的函数。 那么为什么递归如此难以理解呢?

Let’s start things simple. If we were to create a function that would print out the count from 5 to 0, we could do the following:

让我们开始简单。 如果要创建一个将计数从5打印到0的函数,则可以执行以下操作:

function countDownFromFive {
    console.log(5)
    console.log(4)
    console.log(3)
    console.log(2)
    console.log(1)
    console.log(0)
}

But that’s very repetitive, and it can only count from 5 to 0. Ideally, we’d be able to pass in any number, and the function would count down from it. How can we do that?

但这是非常重复的,它只能从5到0进行计数。理想情况下,我们可以传递任何数字,并且该函数将从该数字开始递减计数。 我们该怎么做?

Let’s rename the function to countDownFrom(num), where num would be any positive integer. As for numbers, each number after the first one is — 1 from the previous number. So we could just say num — 1. While we could write this function with a loop, let’s see how we can do it with recursion.

让我们将函数重命名为countDownFrom(num) ,其中num是任何正整数。 对于数字,第一个数字之后的每个数字都是前一个数字的-1。 所以我们只能说num — 1 。 虽然我们可以使用循环编写此函数,但让我们看看如何使用递归来实现。

With recursion, we’ll need to call that function again and again, each time decrementing the number passed into the function. How about something like this:

使用递归时,我们需要一次又一次地调用该函数,每次递减传递给该函数的数字。 这样的事情怎么样:

function countDownFrom(num) {
    console.log(num)
    countDownFrom(num - 1)
}


countDownFrom(5)

Great! Oh, wait, what could go wrong here? The function will start printing numbers starting from 5, then 4, 3, 2, 1, 0 — and it’ll go on into negative numbers because there’s nothing stopping it!

大! 哦,等等,这可能出什么问题? 该函数将开始打印从5开始的数字,然后从4、3、2、1、0开始-它将继续为负数,因为没有什么可以阻止它!

We stumbled into the most important thing about recursion — we need a base case. We need a way to show the function when it should stop calling itself (otherwise it’ll do that forever and you’ll have to press Ctrl + C to get out of that infinite loop!)

我们偶然发现了关于递归的最重要的事情-我们需要一个基本案例。 我们需要一种方法来显示该函数何时停止调用自身(否则它将永远执行下去,并且您必须按Ctrl + C才能退出该无限循环!)

Here’s the updated function, where the recursive case only runs if the number passed in is more than zero. Otherwise (that is when it reaches 0), it prints out “Done! ✅ ”

这是更新的函数,其中递归情况仅在传入的数字大于零时才运行。 否则(即达到0时)将打印出“完成! ””

function countDownFrom(num) {
    if (num > 0){
        console.log(num)
        countDownFrom(num - 1)
    } else {
        console.log("Done! ✅ ")
    }
}


countDownFrom(10)

让我们回顾一下有关递归的最重要的事情: (Let’s recap the most important things about recursion:)

  1. Passed in argument should change for every recursive call. We may be incrementing/decrementing numbers, changing strings or arrays, but we need to change something not to end up in an infinite loop.

    对于每个递归调用,传入的参数都应更改。 我们可能在增加/减少数字,更改字符串或数组,但是我们需要更改某些内容以免陷入无限循环。
  2. We need a base case when the function should stop (again, not to end up in an infinite loop).

    当函数应该停止时(再次,不要以无限循环结束),我们需要一个基本情况。

Let’s look at another example of a recursive function, where we need to add all the numbers in an array up to a passed-in index.

让我们看一下递归函数的另一个示例,在该示例中,我们需要将数组中的所有数字相加直到传入的索引。

Let’s say we have an array [1, 2, 3, 4, 5, 9] and want to add up all the numbers till index 3.

假设我们有一个数组[1, 2, 3, 4, 5, 9] ,想要将所有数字加起来直到索引3

The sum will be array[3] + array[2] + array [1] + array[0]. So what we can do is call the function repeatedly, each time decrementing the index, and add everything up. When we reach the very first element at array[0], we don’t call the function and just return the number at that index.

总和为array[3] + array[2] + array [1] + array[0]. 因此,我们可以做的是重复调用该函数,每次减少索引,然后加总。 当我们到达array[0]第一个元素时,我们不会调用该函数,而只是返回该索引处的数字。

function addUpTo(arr, index) {
    if (index === 0) return arr[0]
    return arr[index] + addUpTo(arr, index - 1)
}

Another example with an array. This time we want to check if the array includes a particular number.

数组的另一个例子。 这次我们要检查数组是否包含特定数字。

What we can do is look at the first number in the array and check if it’s the number we’re looking for. If that’s the case, we return true. If it’s not, we call the function again, this time checking the array without that first number by slicing it away. If we go through all the elements in the array and didn’t find the number, we return false.

我们可以做的是查看数组中的第一个数字,并检查它是否是我们要寻找的数字。 如果是这样,我们返回true。 如果不是,我们再次调用该函数,这次通过将其切开来检查没有第一个数字的数组。 如果我们遍历数组中的所有元素而没有找到数字,则返回false。

function includesNumber(arr, num) {
    if (arr.length === 0) {
        return false
    } else {
        if (arr[0] === num) {
            return true
        } else {
            return includesNumber(arr.slice(1), num)
        }
    }
}

In the end, let’s reverse a string with recursion!

最后,让我们以递归方式反转字符串!

We add the first character at the end of our return statement and then call the function again on a string that was sliced to cut off that first character. When we’re down to the very last character in a string we return that, and then the function bubbles up and returns a reverse string!

我们在return语句的末尾添加第一个字符,然后在切成字符串以切断该第一个字符的字符串上再次调用该函数。 当我们找到字符串中的最后一个字符时,我们将其返回,然后该函数冒泡并返回一个反向字符串!

function reverse(str) {
    if (str.length === 1) return str
    return reverse(str.slice(1)) + str[0]
}


reverse('goodbye')

That’s it for recursion 101! Remember, that you don’t have to use it, but some problems are easier to solve recursively, for example, factorials and Fibonacci.

递归101就是这样! 请记住,您不必使用它,但是某些问题更易于递归解决,例如阶乘和斐波那契。

Image for post

有用的资源: (Helpful Resources:)

A good introduction to recursion for complete beginners
递归入门入门

翻译自: https://code.likeagirl.io/stepping-into-recursion-c5502bc58c9e

递归算法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值