📜  Golang中不同类型的递归

📅  最后修改于: 2021-10-25 02:47:35             🧑  作者: Mango

递归是一个函数通过直接或间接方式调用自身的概念。对递归函数的每次调用都是一个较小的版本,因此它会在某个点收敛。每个递归函数都有一个基本情况或基本条件,它是递归中的最终可执行语句并停止进一步的调用。

有不同类型的递归,如以下示例中所述:

1.直接递归

函数直接调用自身而不需要其他函数帮助的递归类型称为直接递归。下面的例子解释了直接递归的概念:

例子:

// Golang program to illustrate the
// concept of direct recursion
package main
  
import (
    "fmt"
)
  
// recursive function for 
// calculating a factorial 
// of a positive integer
func factorial_calc(number int) int {
  
    // this is the base condition
    // if number is 0 or 1 the
    // function will return 1
    if number == 0 || number == 1 {
        return 1
    }
      
    // if negative argument is 
    // given, it prints error
    // message and returns -1
    if number < 0 {
        fmt.Println("Invalid number")
        return -1
    }
      
    // recursive call to itself
    // with argument decremented 
    // by 1 integer so that it
    // eventually reaches the base case
    return number*factorial_calc(number - 1)
}
  
// the main function
func main() {
  
    // passing 0 as a parameter
    answer1 := factorial_calc(0)
    fmt.Println(answer1, "\n")
      
    // passing a positive integer
    answer2 := factorial_calc(5)
    fmt.Println(answer2, "\n")
      
    // passing a negative integer
    // prints an error message
    // with a return value of -1
    answer3 := factorial_calc(-1)
    fmt.Println(answer3, "\n")
      
    // passing a positive integer
    answer4 := factorial_calc(10)
    fmt.Println(answer4, "\n")
}

输出:

1 

120 

Invalid number
-1 

3628800

2. 间接递归

函数调用另一个函数而该函数又调用调用函数的递归类型称为间接递归。这种类型的递归需要另一个函数的帮助。该函数确实调用了自身,但间接调用,即通过另一个函数。下面的例子解释了间接递归的概念:

例子:

// Golang program to illustrate the
// concept of indirect recursion
package main
  
import (
    "fmt"
)
  
// recursive function for 
// printing all numbers 
// upto the number n
func print_one(n int) {
      
    // if the number is positive
    // print the number and call 
    // the second function
    if n >= 0 {
        fmt.Println("In first function:", n)
        // call to the second function
        // which calls this first
        // function indirectly
        print_two(n - 1)
    }
}
  
func print_two(n int) {
  
    // if the number is positive
    // print the number and call 
    // the second function
    if n >= 0 {
        fmt.Println("In second function:", n)
        // call to the first function
        print_one(n - 1)
    }
}
  
// main function
func main() {
      
    // passing a positive 
    // parameter which prints all 
    // numbers from 1 - 10
    print_one(10)
      
    // this will not print
    // anything as it does not
    // follow the base case
    print_one(-1)
}

输出:

In first function: 10
In second function: 9
In first function: 8
In second function: 7
In first function: 6
In second function: 5
In first function: 4
In second function: 3
In first function: 2
In second function: 1
In first function: 0

注意:只有 2 个函数的间接递归称为相互递归。可以有两个以上的函数来促进间接递归。

3. 尾递归

尾调用是一个子程序调用,它是函数的最后或最后调用。当尾调用执行对同一函数的调用时,该函数被称为尾递归的。在这里,递归调用是函数执行的最后一件事。

例子:

// Golang program to illustrate the
// concept of tail recursion
package main
  
import (
    "fmt"
)
  
// tail recursive function
// to print all numbers 
// from n to 1
func print_num(n int) {
      
    // if number is still 
    // positive, print it
    // and call the function
    // with decremented value
    if n > 0 {
        fmt.Println(n)
          
        // last statement in 
        // the recursive function
        // tail recursive call
        print_num(n-1)
    }
}
  
// main function
func main() {
      
    // passing a positive 
    // number, prints 5 to 1
    print_num(5)
}

输出:

5
4
3
2
1

4. 头递归

在头递归中,递归调用是函数的第一条语句。调用之前没有其他语句或操作。该函数在调用时不必处理任何事情,所有操作都在返回时完成。

例子:

// Golang program to illustrate the
// concept of head recursion
package main
  
import (
    "fmt"
)
  
// head recursive function
// to print all numbers 
// from 1 to n
func print_num(n int) {
      
    // if number is still 
    // less than n, call 
    // the function
    // with decremented value
    if n > 0 {
          
        // first statement in 
        // the function
        print_num(n-1)
          
        // printing is done at
        // returning time
        fmt.Println(n)
    }
}
  
// main function
func main() {
      
    // passing a positive 
    // number, prints 5 to 1
    print_num(5)
}

输出:

1
2
3
4
5

注意:头递归的输出与尾递归的输出正好相反。这是因为尾递归首先打印数字然后调用自身,而在头递归中,函数不断调用自身直到达到基本情况,然后在返回期间开始打印。

5. 无限递归

所有的递归函数都是定递归函数或有限递归函数,即它们在达到基本条件时停止。无限递归是一种递归,它一直持续到无穷大并且永远不会收敛到基本情况。这通常会导致系统崩溃或内存溢出。

例子:

// Golang program to illustrate the
// concept of infinite recursion
package main
  
import (
    "fmt"
)
  
// infinite recursion function
func print_hello() {
      
    // printing infinite times
    fmt.Println("GeeksforGeeks")
    print_hello()
}
  
// main function
func main() {
      
    // call to infinite 
    // recursive function
    print_hello()
}

输出:

GeeksforGeeks
GeeksforGeeks
GeeksforGeeks
..... infinite times

6.匿名函数递归

在 Golang 中,有一个没有名字的函数的概念。此类函数称为匿名函数。递归也可以在 Golang 中使用匿名函数进行,如下所示:

例子:

// Golang program to illustrate 
// the concept of anonymous 
// function recursion
package main
  
import (
    "fmt"
)
  
// main function
func main() {
      
    // declaring anonymous function
    // that takes an integer value
        var anon_func func(int)
           
    // defining an anonymous
    // function that prints
    // numbers from n to 1
        anon_func = func(number int) {
      
        // base case
            if number == 0 {
                    return 
            } else {
            fmt.Println(number)
              
            // calling anonymous 
            // function recursively
                    anon_func(number-1)
            }
        }
      
    // call to anonymous 
    // recursive function
        anon_func(5)
}

输出:

5
4
3
2
1

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程