- I+ x- S: V; X9 l e j 经典示例:计算阶乘; C$ p. M4 C2 E$ M3 A
python : ^8 N, m* E9 I2 N& e) _& |def factorial(n): 3 }/ q5 H1 N$ B P2 j# X" \ if n == 0: # 基线条件 6 U S* Q$ k( ]; \& p$ j2 S return 1 . H5 p( D1 I/ g/ g$ w# n else: # 递归条件# \# x' x( G7 \1 D
return n * factorial(n-1)! _! N p1 e7 H7 Y& Y8 V
执行过程(以计算 3! 为例): 2 K4 k0 e7 l9 cfactorial(3) # d2 u- C; U. o3 * factorial(2) 4 f) u Y0 W1 e0 d4 `4 P3 * (2 * factorial(1))' w+ e ?0 y1 E
3 * (2 * (1 * factorial(0))) 7 {1 \- B6 l0 w$ U8 r* e3 * (2 * (1 * 1)) = 64 ^/ b( L) ^8 G) x0 K
# c3 `/ g# [ q: F/ | 递归思维要点 - y3 i0 M8 [& D! _8 O* z6 ?. N1. **信任递归**:假设子问题已经解决,专注当前层逻辑 " S: i/ z6 i t9 E$ O4 E2. **栈结构**:每次调用都会创建新的栈帧(内存空间)+ {- \& B6 {$ w/ M
3. **递推过程**:不断向下分解问题(递) 9 }! X' W9 N6 H$ r4. **回溯过程**:组合子问题结果返回(归) 9 h# T3 b/ v! [1 d/ v' E ) k7 W' P) _5 ]6 N 注意事项. {; k* z' o/ j2 ]
必须要有终止条件8 M& }0 o& G4 o; y2 J3 D
递归深度过大可能导致栈溢出(Python默认递归深度约1000层)# o5 I+ G# m2 P* E, c
某些问题用递归更直观(如树遍历),但效率可能不如迭代% M* l+ Z( C& V4 Z+ f8 x0 }
尾递归优化可以提升效率(但Python不支持) + y8 T! a. t3 _" v, U: w% c( X# _: p2 u
递归 vs 迭代 * J( F: W- S L% X5 |' O| | 递归 | 迭代 | % g" W% Q; ~( u|----------|-----------------------------|------------------|8 A0 e# u" _+ i: @" D2 H
| 实现方式 | 函数自调用 | 循环结构 | ` i; m9 u$ I5 `* [* m, \2 H| 内存消耗 | 需要维护调用栈(可能溢出) | 通常更节省内存 | 5 n7 V& h8 ^! t$ {/ S! |0 D( \$ d| 代码可读性 | 对符合递归思维的问题更直观 | 线性流程更直接 |% z" L4 w; X" x4 g& b% Z
| 适用场景 | 树结构、分治算法、回溯问题等 | 简单重复操作 | 1 n, _3 m; b: u/ E1 ^ k ! n: X/ \# ^0 E- J" C 经典递归应用场景 6 u& H, Z6 H: V: @3 Y1. 文件系统遍历(目录树结构) , ?6 r6 Y) r) d9 E2. 快速排序/归并排序算法; Z/ c) }: W0 z
3. 汉诺塔问题 % o! `1 ^; K) i! e4 f4. 二叉树遍历(前序/中序/后序) * o, v. W. F7 a! ]2 F6 B' l5. 生成所有可能的组合(回溯算法)5 [4 [( O- f# E2 M( h
8 L) M. O& a1 E& `7 X- [4 E
试着用递归思维想象:你站在一面镜子前,镜子里有无数个逐渐变小的你在照镜子,这就是递归的直观体现。但记住每个"分身"最终都要有结束的时刻,这就是基线条件的重要性。作者: testjhy 时间: 2025-1-30 00:07
挺好,递归思维要点与我能够回忆起来我当时写递归程序的思路很一致,,或者被它唤醒,( \# k* c+ F; `: `: N( Q; y
我推理机的核心算法应该是二叉树遍历的变种。6 e: ]: U6 P+ b4 p# f. N, v; F
另外知识系统的推理机搜索深度(递归深度)并不长,没有超过10层的,如果输入变量多的话,搜索宽度很大,但对那时的286-386DOS系统,计算压力也不算大。作者: nanimarcus 时间: 2025-2-2 00:45
Recursion in programming is a technique where a function calls itself in order to solve a problem. It is a powerful concept that allows you to break down complex problems into smaller, more manageable subproblems. Here's a detailed explanation: + z( _; V) D* e3 W+ x5 J7 kKey Idea of Recursion& `# C! \9 g! g8 d$ _/ _
& C1 [2 C4 V; f/ ?" }& }
A recursive function solves a problem by:. [9 r8 N" x+ U1 f; {0 o
X- f& A- J& y. X3 w; ^
Breaking the problem into smaller instances of the same problem. ! S" B7 x( T& q: x- z0 R8 _. {$ C1 v/ I+ [3 M- {; U4 q
Solving the smallest instance directly (base case). * ]: [$ a! r1 h. D( a q, B" n2 v " F# A# K: P7 ?# G: \3 z Combining the results of smaller instances to solve the larger problem. # X8 }7 c1 S5 q: q2 L7 p N: j) _; y: l, M4 z# l4 L% d- V
Components of a Recursive Function 5 e! {5 y0 j, t4 N p+ z- i+ } # }' v! H" D" H# V Base Case: 1 e6 E$ a6 `' F8 m) ~7 Z) I3 H+ `8 ~! |2 o' l9 F/ f% T
This is the simplest, smallest instance of the problem that can be solved directly without further recursion. 9 l& P1 f1 X/ H$ Q( H+ |6 a& p" @& w1 j! t2 `
It acts as the stopping condition to prevent infinite recursion. , d2 H1 D$ v6 v$ z! O 4 B1 ?0 N' J8 [* T1 t0 M Example: In calculating the factorial of a number, the base case is factorial(0) = 1. - y/ F+ n) p! o4 @) A; g: t+ k* p' ^3 E' r: f4 n( {
Recursive Case:. u1 ^4 I5 C) m- N9 P
7 ?) {" ]% @4 t3 G8 @
This is where the function calls itself with a smaller or simpler version of the problem. * r$ u+ J2 T- U: ^ 2 g3 L ^2 M4 G+ ?+ v/ w" P Example: For factorial, the recursive case is factorial(n) = n * factorial(n-1).7 q# D1 L) O% y
+ T) c5 U: [+ W4 u+ {Example: Factorial Calculation 1 [% k0 H- Q4 m9 o6 ~% A: N+ _: G/ C( @# m( Y- m/ R
The factorial of a number n (denoted as n!) is the product of all positive integers less than or equal to n. It can be defined recursively as: 6 ?6 _6 C/ i9 `; Q' N/ U# j- k" w* E3 j% O: ?8 _8 F G
Base case: 0! = 1+ S/ x4 L3 h% N
% a7 }1 u! d0 j- {% f X+ H Recursive case: n! = n * (n-1)!# F8 _5 _5 ^% T+ @: x: a
7 j% e. ]% [# u, \! l, x
Here’s how it looks in code (Python): 9 M Z' Y+ \5 \- D4 ^. O! N) Rpython % _ @1 U P, R+ u, v3 l1 P$ n* n & ^; ]& K3 W, l7 m$ y" `7 ^ 6 J7 ]: E7 y; xdef factorial(n):# o. C4 L3 `: t
# Base case2 X. S, X3 u4 `1 J+ ?5 F% c
if n == 0: 1 Q/ m6 W- W( q/ j' L5 s# V! u return 1 + s; T! g5 d5 U) ` # Recursive case( B: e8 L+ ?2 r
else: ( y7 `# l/ [0 v! G% U! t( M) C return n * factorial(n - 1)9 V2 `8 @, O# Z+ v; Q h
1 C+ l P& p% U( H+ |How Recursion Works ^0 ^% b$ Q, G/ g* x, v0 l: O4 G; }+ M( c; f6 M
The function keeps calling itself with smaller inputs until it reaches the base case.1 t: ]# y/ K. z; X) U+ V
# B! h& C: p# z6 ]
Once the base case is reached, the function starts returning values back up the call stack.# } h/ V4 }6 w
* @- i" Z3 } d7 G These returned values are combined to produce the final result. . F3 {% G% w- X2 f* P! d1 w& j! R3 t6 s/ [* m
For factorial(5): , x- A. z, q Q+ r 7 \0 x J: n' l3 R3 S7 \+ [# j1 |6 f , `& N+ N8 g- n; ~7 c/ jfactorial(5) = 5 * factorial(4) ! I& z% e/ e5 `( p: B: v: | Cfactorial(4) = 4 * factorial(3)# w7 ?+ y7 U/ B
factorial(3) = 3 * factorial(2) % r5 W4 H. Z: e. L4 l. Gfactorial(2) = 2 * factorial(1)7 a' N6 B3 L0 O" k
factorial(1) = 1 * factorial(0) ' R8 \" }6 l7 c6 \$ m E3 Ufactorial(0) = 1 # Base case' \* T; \. l1 i" _8 t5 n8 Y
5 P- _2 d8 P' s. Z7 u+ T4 VThen, the results are combined:& ~* b8 V- `) I \6 H" Q3 }
! \$ A* |7 R8 G5 N8 m; ]$ M
+ a. _- w$ C0 m0 |) A! F
factorial(1) = 1 * 1 = 1# V( O2 G F3 f4 ^$ V4 U5 s
factorial(2) = 2 * 1 = 29 U6 t2 v% g% L/ O5 P7 U& p2 ]
factorial(3) = 3 * 2 = 62 ~/ ?) w8 o6 d/ K" { M) R5 @& j
factorial(4) = 4 * 6 = 24 ' H4 S$ I1 r; g, l+ ~: gfactorial(5) = 5 * 24 = 120 + E, G$ W O F$ T+ E 5 w8 K$ s- `8 D, FAdvantages of Recursion r, O1 g/ q" b, E* w
% g* g7 o6 z, m w! U3 |, |5 k
Simplicity: Recursive solutions are often more intuitive and easier to write for problems that have a natural recursive structure (e.g., tree traversals, divide-and-conquer algorithms). 9 {$ |. L# J A5 v' k/ y; t % w: P' n* Q2 X$ d, o5 x Readability: Recursive code can be more readable and concise compared to iterative solutions.: Z3 Q" n1 D: r
$ [3 }: W! ~. B$ x% DDisadvantages of Recursion, R# @) S/ R; e! Q) O
! Q& T$ B+ P" F0 L$ h Performance Overhead: Each recursive call adds a new layer to the call stack, which can lead to high memory usage and potential stack overflow for deep recursion.- \9 ?/ V; `! _5 {' X
/ W: F) h* U; k, P) G
Inefficiency: Some problems can be solved more efficiently using iteration (e.g., Fibonacci sequence without memoization).: Q7 ?, ^' o6 D/ P4 @
* [0 F# Z! W8 \# B* S8 c1 V; Y" wWhen to Use Recursion ( ?' v) ?& l) S2 U 5 q$ r' o! O' Z' `7 G Problems that can be broken down into smaller, similar subproblems (e.g., tree traversals, sorting algorithms like quicksort and mergesort). " d/ e) v# z/ m) _9 C9 S# x) x8 I% W
Problems with a clear base case and recursive case.# c, j2 D$ _7 o0 @3 R p2 `+ c) A; M9 E
, x# I; i1 n2 \1 J# x
Example: Fibonacci Sequence2 t4 V1 j: H/ A4 y/ A) ^4 g0 C2 n
6 x; `% f. @/ U. F! d5 u% @The Fibonacci sequence is another classic example of recursion. Each number is the sum of the two preceding ones: ' [$ [( p, w" [. U& Y2 F) V3 y$ ~ 7 `" h6 h l# o0 h; C Base case: fib(0) = 0, fib(1) = 17 F) J! q% | a& Y v5 K+ e1 Z( p6 J# I2 j
8 ?+ @2 K1 t2 f Y Recursive case: fib(n) = fib(n-1) + fib(n-2) ! z: x% n: ]) H. b6 ?/ x; x' ^( c9 N% M0 I" _
python; P5 E. x" l/ E1 c
+ G* P6 b* ~8 r
8 |' {) g; A! H/ p1 L. T W! zdef fibonacci(n): + D! ]( u' H$ I) J; H! g0 M& s # Base cases: l+ f' e X* S8 T4 o
if n == 0:. [* [: L c; V: ]6 U4 Z! @
return 07 \6 _+ t9 j3 D# K* ~/ V
elif n == 1:& f$ U0 _$ t0 D6 F* k, R; r5 |% Q7 X
return 1 2 b, Q$ N. f% m' a0 F W$ r+ v" Z # Recursive case0 U+ g9 j& _; B' G" W
else: + U5 F8 ]3 Z( y i; s0 i* L( m. K return fibonacci(n - 1) + fibonacci(n - 2) 5 ?$ a+ E4 U4 A7 Y% Z 0 y/ i1 `* ]! T! H B! |# Example usage / f8 ^( M$ o- D( e& s. I5 f5 @print(fibonacci(6)) # Output: 8 2 v4 E9 W5 D, b! }' K. M# P: l- I, ]4 h4 I; f Q; y8 ~6 d# r
Tail Recursion1 Z& c# \8 b3 J9 f
& M/ T8 B$ H* B5 J- L, DTail recursion is a special case of recursion where the recursive call is the last operation in the function. Some programming languages optimize tail-recursive functions to avoid stack overflow, but not all languages (e.g., Python does not optimize tail recursion).* C1 @3 M/ G8 \
6 I) o1 t: S- K9 o/ Q/ L* e& ~/ A
In summary, recursion is a fundamental concept in programming that allows you to solve problems by breaking them into smaller, self-similar subproblems. It’s important to define a base case to avoid infinite recursion and to understand the trade-offs between recursion and iteration.作者: nanimarcus 时间: 2025-2-2 00:47
我还让Deepseek 给我讲讲Linux Kernel Driver 现在的开发流程,让一个老同志复习复习,快忘光了。