+ h9 N }. X3 }* Z. P 关键要素0 t, A/ k$ Q. q, m
1. **基线条件(Base Case)** & @3 T# ?/ z; u# a5 v" _ - 递归终止的条件,防止无限循环 # |2 V2 H& `9 S9 J0 `0 w - 例如:计算阶乘时 n == 0 或 n == 1 时返回 1 1 v% `8 K; G( @% [+ F" c# P: i2 r1 c5 z2 Q% p
2. **递归条件(Recursive Case)** 2 s$ }; A5 k& L4 o2 t& |1 S( W* W, m - 将原问题分解为更小的子问题# f( w! n6 ~' G' r9 R2 W/ P
- 例如:n! = n × (n-1)!/ h; z5 h! B! F) ?' F" R
3 @( X2 P1 W: m! Y6 a6 A0 H 经典示例:计算阶乘$ Q$ K: d6 [. }5 \, t; A9 |
python 1 }3 u3 G% c* Jdef factorial(n):: K* Q0 n9 @0 A9 A; d; H1 [
if n == 0: # 基线条件1 ]5 K! V* I- ?+ u$ t t4 I) t
return 1 % v" P$ `1 |% G% l: ~ else: # 递归条件 8 O/ A Q. w) i, P: W# ]) W5 t return n * factorial(n-1) " t4 \6 z& p3 g* \( q# L, m执行过程(以计算 3! 为例):6 C" _6 s: x. [. L" \/ `1 u# N
factorial(3)9 \) b" O0 Z1 G* f! M; E, V
3 * factorial(2)! ~% V& V5 G5 g3 l. b3 }& q
3 * (2 * factorial(1)) 0 \# `) m1 x/ {3 * (2 * (1 * factorial(0))) 3 A, i0 \3 U2 D+ |3 U3 * (2 * (1 * 1)) = 6 6 G x6 m$ B3 Q6 l1 t ' H0 n# f8 _0 ~ 递归思维要点 6 d; q& j1 a7 L, K( T) l7 m1. **信任递归**:假设子问题已经解决,专注当前层逻辑 9 a4 z/ C( e% c. }# N% [0 Y- ]9 k2. **栈结构**:每次调用都会创建新的栈帧(内存空间)" Z2 r$ M9 \7 O2 g6 m. K
3. **递推过程**:不断向下分解问题(递)2 E& a( m5 J" O; k1 w
4. **回溯过程**:组合子问题结果返回(归)& [6 }8 v7 O0 Z9 z
0 i8 T0 W* r* I& ?
注意事项/ N8 T; K8 u! Q# y- d
必须要有终止条件% z* d/ x4 }6 F
递归深度过大可能导致栈溢出(Python默认递归深度约1000层) ) \% f, [! V. `4 h% l: P某些问题用递归更直观(如树遍历),但效率可能不如迭代 2 N# _! d6 m7 k8 a. x尾递归优化可以提升效率(但Python不支持), L$ I9 k3 z6 M, q; r
' N* a0 n' L! o% | 递归 vs 迭代 $ i! ]9 N) l1 x& ]| | 递归 | 迭代 | # h6 a1 v# k3 N|----------|-----------------------------|------------------| ) J7 @ M! H* |/ z5 \| 实现方式 | 函数自调用 | 循环结构 |: V0 c$ V# W; {. C8 v7 j
| 内存消耗 | 需要维护调用栈(可能溢出) | 通常更节省内存 |5 Z4 i' O: O4 T3 E; D* Q6 u
| 代码可读性 | 对符合递归思维的问题更直观 | 线性流程更直接 |: n: m, N+ R4 Y1 r& {
| 适用场景 | 树结构、分治算法、回溯问题等 | 简单重复操作 |+ j; X( f2 E% j! v1 h
- o ^* }7 c7 h8 ]* r
经典递归应用场景 $ \. j- u& }0 Y3 i0 `* Q" Q* a1. 文件系统遍历(目录树结构) / z& b# ]9 J" u @# B- Z$ `2 B; S2. 快速排序/归并排序算法 / y9 v: W Y0 w: c: }! K3. 汉诺塔问题 ; a# D7 |" k' \; z0 p4. 二叉树遍历(前序/中序/后序)$ H# m5 |6 {* s; T" N4 W. u
5. 生成所有可能的组合(回溯算法) * W; j9 z- R# K- C) `- V* w' n& N + `7 ]9 B. }: w* }" W& w试着用递归思维想象:你站在一面镜子前,镜子里有无数个逐渐变小的你在照镜子,这就是递归的直观体现。但记住每个"分身"最终都要有结束的时刻,这就是基线条件的重要性。作者: testjhy 时间: 2025-1-30 00:07
挺好,递归思维要点与我能够回忆起来我当时写递归程序的思路很一致,,或者被它唤醒,3 n: k% _5 l. u
我推理机的核心算法应该是二叉树遍历的变种。+ v' }- O$ z. m; T6 G
另外知识系统的推理机搜索深度(递归深度)并不长,没有超过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:1 y+ E5 ~" X6 |, x' ^3 V- B7 J
Key Idea of Recursion ( U; j* N4 Z# _( `; v0 C" s% U- D 2 D: f, [$ A# wA recursive function solves a problem by:$ D8 |9 U% G3 p% S; u
/ I3 q/ ~+ ? p: @; G% I4 a$ {' U Breaking the problem into smaller instances of the same problem.) M8 M6 |+ o$ n7 w5 @! _5 H2 U
) V9 x2 k. i" ], L- r/ M
Solving the smallest instance directly (base case). * z0 } A) z, b & _' F2 R4 q) c3 `- Y Combining the results of smaller instances to solve the larger problem.; i" Y3 w7 b4 j% F
; u6 S0 m5 G. v+ E! KComponents of a Recursive Function4 X" x# |! u1 o9 Q7 @ Y
' H/ u9 }" @, _$ p' h3 X0 Z1 b! B5 @5 l
Base Case:- j* L) v1 w6 M/ }/ T# h
; A! v1 G% X4 X7 a+ _: \2 M This is the simplest, smallest instance of the problem that can be solved directly without further recursion. 4 r1 i7 t; I: U) s* O, W/ l8 }. ]) y: x4 k7 x
It acts as the stopping condition to prevent infinite recursion.0 W5 Z2 ~; I, E" H! P& O
- v3 b& W( O3 V4 |' o) \4 h7 m' D% F Example: In calculating the factorial of a number, the base case is factorial(0) = 1.0 s. `* x& U) h8 G+ B, h
) N9 e& @1 r2 w, z Recursive Case:7 O8 o, V0 r6 [: c6 b% c
# N* d( t/ `5 ^9 \2 k! b! X
This is where the function calls itself with a smaller or simpler version of the problem. ( @$ y% f9 {9 }- f' e7 Y' h. {: v' @- ~" ^
Example: For factorial, the recursive case is factorial(n) = n * factorial(n-1).9 E: }9 W0 I0 m% Q
+ M; \6 k2 Z/ z7 T- _! o
Example: Factorial Calculation & L1 v' j) J$ I. N' w+ I3 L! f$ E$ q* _9 e3 |3 ?8 I6 l
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: " i3 u2 {3 y( n7 `- B# Z$ I+ Q' \$ x2 ~- Q* n% S: o% ]4 o
Base case: 0! = 1 " q5 ]9 D4 Q3 {& a5 i! i8 W( E, A! \2 R1 e0 k+ |' \7 c
Recursive case: n! = n * (n-1)! 8 G1 j* j5 p9 x: H& E) P3 Q0 f" ?3 m' j
Here’s how it looks in code (Python): % J$ j9 ~! T8 d9 g! l- t8 Qpython' Q# \, A7 a3 ]% d/ U6 M
- p0 \% H& b* z5 a' C5 |; E
' ]; x( X Q# G: R; X/ fdef factorial(n):( h6 U+ a/ C7 S( S3 o* k* _, ?
# Base case 7 t' O% j) o: A. a if n == 0: 6 @* {# F, I5 M0 b8 A# Q+ U& d return 1 5 ~- Y+ }7 K+ O! E # Recursive case0 r6 m5 F. Q, j' e6 o0 r
else:5 H6 ?$ c3 e& R' u
return n * factorial(n - 1) 8 ~$ S, f8 E4 [, X2 P8 X# A : W+ X8 I E7 T# f# Example usage 1 O# J( s' t$ Lprint(factorial(5)) # Output: 1200 w! p0 X# X6 d8 U$ s
- O( R1 ?" w5 n1 T2 _: b: _. O
How Recursion Works 2 J5 N; t( G" Z/ y! ] 2 G9 t* e/ I. k The function keeps calling itself with smaller inputs until it reaches the base case.$ c3 a1 l7 Y& g+ u+ ]% B5 X
# u) L$ P- ~( d- F$ g4 z/ R7 p0 R
Once the base case is reached, the function starts returning values back up the call stack. 2 @ R$ E. B8 x- b( T ) X& h! Q5 J. f These returned values are combined to produce the final result. 9 p1 Z( F i% f! X( d( L2 p u! T 8 k; ]- P" g/ @4 T% g( vFor factorial(5):9 ]# s* W% P4 b% E F; u) C$ o
: G9 e% e: j; {7 C. {3 y+ N+ W. C6 M
% U3 M4 S- p; s5 x1 f9 e- j2 ]
factorial(5) = 5 * factorial(4) $ M. T% m: E9 b8 m. O# u3 Lfactorial(4) = 4 * factorial(3) 8 R2 X" M j/ y. I# J3 mfactorial(3) = 3 * factorial(2)$ {5 r, |8 B7 n8 A" Z C Q$ Q& d
factorial(2) = 2 * factorial(1) ( ?+ f6 _: d- A, z- [8 z7 ifactorial(1) = 1 * factorial(0)* N$ n% o$ {: q8 h+ b: Z. y
factorial(0) = 1 # Base case 6 l3 R6 i! S f' r& S/ Y: x# A- _: @
Then, the results are combined:* a" n6 t R7 R2 w5 P. ]7 o
4 Z. s! G7 r; }' e ' z# B# c1 b2 @7 o+ nfactorial(1) = 1 * 1 = 1$ P0 S# v: I7 ~% \/ X" ~$ \7 x
factorial(2) = 2 * 1 = 29 N1 _/ F, z* C( b9 b0 l
factorial(3) = 3 * 2 = 63 }- p# i; i; b6 ?* ?& H, [( ?: U
factorial(4) = 4 * 6 = 24 ) O4 w( a+ O3 W+ A; _' Tfactorial(5) = 5 * 24 = 120 $ ]1 Z; \ n( d3 [, C0 P. h ?0 S6 K3 M5 o: w- f% k1 u
Advantages of Recursion ; y1 H) \0 V$ U# f G( B. ]& }$ Q' Z) w/ B# `% g
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). & w" W+ R; s+ `" _ + Z! a6 g' X% Z& x Readability: Recursive code can be more readable and concise compared to iterative solutions.9 h! l& Y" m: N D
" a! Y0 _! _; o, l" K9 l4 `, K
Disadvantages of Recursion4 l5 o! s4 N+ k7 _( A# }6 ]8 Z
; o6 D* ]% L" s9 s/ m* W 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.: U) t, {4 r: y
1 o. x1 w3 J, L! i Inefficiency: Some problems can be solved more efficiently using iteration (e.g., Fibonacci sequence without memoization). 0 W' w* l. p5 j9 J( P+ V5 { 7 Z3 i1 v/ j' g' k7 [4 v' dWhen to Use Recursion/ w* H; C8 U- W" H
9 i: Y1 z* Q0 e0 S4 c+ J& b Problems that can be broken down into smaller, similar subproblems (e.g., tree traversals, sorting algorithms like quicksort and mergesort).' i- g! ^# F) P- ~/ C
8 D+ ^3 y* {$ L, [ _ q
Problems with a clear base case and recursive case.5 ]- @6 P2 G6 x4 |: u# ^: {; G, N
* _/ B8 F! g ~0 d. P9 R" EExample: Fibonacci Sequence $ \2 L& i" A1 X1 k6 G1 e, }! K$ y/ A6 ~/ ]( k: H5 p
The Fibonacci sequence is another classic example of recursion. Each number is the sum of the two preceding ones:' n; w5 q) ?3 E
! N- y1 R O( [4 O h& a6 c Base case: fib(0) = 0, fib(1) = 1* g {: \- d( Z6 z" g
' K D( {$ {& G. u
Recursive case: fib(n) = fib(n-1) + fib(n-2)7 Y e; e% [% F3 }3 ]( X
9 ^! i( H5 X) l
python! Q/ v: B/ Y& t) M; D5 l
% H3 B1 J& B( i6 M9 x
7 h& z& d% l* |$ M+ cdef fibonacci(n): , R5 G' I* e E1 E( Q- F$ S- o # Base cases 8 w1 O c. |1 o1 B6 G4 T u if n == 0:# e9 {$ {1 c2 r
return 0 0 G6 O2 \# X1 K elif n == 1: 0 n o4 y0 x& L g. r return 1 " B. I) e" M3 g # Recursive case Y- d, K0 W' x
else: 7 v( V1 \! p5 h7 J# z% [ return fibonacci(n - 1) + fibonacci(n - 2) + [ u7 G Y4 ]+ J9 j! O. f4 q. f0 n6 p" `6 F7 D# c6 |
# Example usage , H# `, J9 s: D6 p8 z2 X' V4 cprint(fibonacci(6)) # Output: 8 9 t# k a) k$ U# Z( P- ]6 X, v. y+ ]) h* w* i
Tail Recursion/ O) ?5 i1 m3 ^1 f: u( R
" E$ ^' n! }( z. S( j# t+ S( ~Tail 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).9 ?% L) f5 a* J
3 v/ `) F% w9 `6 P! n
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 现在的开发流程,让一个老同志复习复习,快忘光了。