Tail Recursion

A function is tail recursive if it calls itself recursively but does not perform any computation after the recursive call returns, and immediately returns to its caller the value of its recursive call.

非尾递归举例:

let rec fib n = 
  match n with
  | 0 -> 0
  | 1 -> 1
  | _ -> (fib (n - 1) + fib (n - 2));;

尾递归举例:

let rec fib n res1 res2 = 
  match n with
  | 0 -> res1
  | _ -> fib (n - 1) (res2) (res1 + res2);;

When a function makes a recursive call to itself and there is nothing more for the caller to do after the callee returns (except return the callee's result), this situation is called a tail call. Functional languages like OCaml (and even imperative languages like C++) typically include an hugely useful optimization: when a call is a tail call, the caller's stack-frame is popped before the call—the callee's stack-frame just replaces the caller's. This makes sense: the caller was just going to return the callee's result anyway.

CSAPP 中运行时栈的知识可知,当涉及长列表的递归时,尾递归可以优化空间复杂度

So when you have a choice between using a tail-recursive vs. non-tail-recursive function, you are likely better off using the tail-recursive function on really long lists to achieve space efficiency.

But that doesn't mean that a tail-recursive implementation is strictly better. For example, the tail-recursive function might be harder to read.

posted @ 2024-02-02 11:08  sysss  阅读(10)  评论(0编辑  收藏  举报