递归的概念

简单的说:递归就是函数/方法自己调用自己,每次调用时传入不同的变量。递归有助于编程者解决复杂的问题,同时可以让代码变得简洁。

递归的三大要素

  1. 明确你这个函数想要干什么
  2. 寻找递归结束条件
  3. 找出函数的等价关系式

image.png
image.png

代码

  1. // 递归
  2. package main
  3. import "fmt"
  4. func test(n int) {
  5. if n > 2 {
  6. n--
  7. test(n)
  8. }
  9. fmt.Println("test n = ", n)
  10. }
  11. func test02(n int) {
  12. if n > 2 {
  13. n--
  14. test02(n)
  15. } else {
  16. fmt.Println("test02 n = ", n)
  17. }
  18. }
  19. func main() {
  20. test(4)
  21. test02(4)
  22. }
  23. /*
  24. test n = 2
  25. test n = 2
  26. test n = 3
  27. test02 n = 2
  28. */

递归需要遵守的重要原则

  1. 执行一个函数时,就创建一个新的受保护的独立空间(新函数栈)
  2. 函数的局部变量是独立的,不会相互影响。如果希望各个函数栈使用同一个数据,则使用引用传递。
  3. 递归必须向退出递归的条件逼近,否则就是无限递归,死龟了:)
  4. 当一个函数执行完毕,或者遇到return,就会返回,遵守谁调用,就将结果返回给谁,同时当函数执行完毕或者返回时,该函数本身也会被系统销毁

    应用场景

  • 排序
  • 二分查找
  • 阶乘
  • 斐波那契数列
  • 猴子吃桃(每一天吃当天桃子数量的一半多1个)
  • 8皇后问题
  • 汉诺塔(移动圆饼,小的在上,大的在下)
  • 迷宫问题
  • 球和篮子
  1. // 函数递归调用 + 应用场景
  2. package main
  3. import "fmt"
  4. func test(n int) {
  5. if n > 2 {
  6. n--
  7. test(n)
  8. }
  9. fmt.Println("n = ", n)
  10. }
  11. func test2(n int) {
  12. if n > 2 {
  13. n--
  14. test2(n)
  15. } else {
  16. fmt.Println("n = ", n)
  17. }
  18. }
  19. // 斐波那契数
  20. func fbn(n int) int {
  21. if n == 1 || n == 2 {
  22. return 1
  23. } else {
  24. return fbn(n-2) + fbn(n-1)
  25. }
  26. }
  27. // 猴子吃桃子
  28. // 每一天吃当天桃子数量的一半多1个,第十天的时候发现只剩下一个
  29. // 求第一天的桃子数量
  30. func peach(n int) int {
  31. if n > 10 || n < 1 {
  32. fmt.Println("您输入的天数不对")
  33. return 0
  34. }
  35. if n == 10 {
  36. return 1
  37. } else {
  38. return (peach(n+1) + 1) * 2
  39. }
  40. }
  41. func main() {
  42. test(4)
  43. // test2(4)
  44. // 斐波那契数列
  45. // 1 ,1 ,2 ,3 ,5 ,8, 13 ,21 ,......
  46. // f(n) = f(n-2) + f(n-1)
  47. fmt.Println("value=", fbn(5)) // 第5个斐波那契数
  48. // fmt.Println("value=", fbn(6)) // 第6个斐波那契数
  49. // fmt.Println("value=", fbn(7))
  50. // fmt.Println("value=", fbn(8))
  51. fmt.Println("第1天的桃子数量", peach(1))
  52. }