* l" H n3 x0 o8 W" F0 K1 s C 关键要素2 n2 ^* n& L9 y4 Y. Z
1. **基线条件(Base Case)**; K" ]1 M7 [3 `. c/ O8 {
- 递归终止的条件,防止无限循环 3 Y7 e5 Z" R8 L3 w2 W9 s - 例如:计算阶乘时 n == 0 或 n == 1 时返回 1 # _2 v5 H5 Y" _2 I 5 y6 H9 T X, X9 K! K1 U7 e2. **递归条件(Recursive Case)** 2 G+ L+ y8 r5 ]# S* G4 T, U) ~ - 将原问题分解为更小的子问题 ) p/ ?# P- o' b- q7 Z - 例如:n! = n × (n-1)!. W' W6 e7 q9 \3 X
1 a+ l! t, G5 Y- x4 V 经典示例:计算阶乘 $ Q. n8 a Y. J0 i! ~% U/ @python # T4 z' m f1 Pdef factorial(n):' z- _6 L3 C" Q% I3 r+ G, U
if n == 0: # 基线条件' H' v$ P. D3 d3 q
return 1 , V5 j* s/ R1 I& h else: # 递归条件 + h$ f3 S6 j [; u6 x @ return n * factorial(n-1) 5 c6 C3 Y2 D# ]# O: o执行过程(以计算 3! 为例): 4 A& O% t/ M7 u* w& \factorial(3) I, P1 t/ z3 w. ^' Q' n3 * factorial(2)2 z5 I# ]7 G$ E2 F# K a
3 * (2 * factorial(1)): V# [# {7 k' v' }$ u3 x1 \5 Y G
3 * (2 * (1 * factorial(0))) * P0 a( @3 Y6 x, v( J3 v3 * (2 * (1 * 1)) = 6 ( g( ~! y/ e. R' R, ?$ F8 D1 b0 ^7 @4 e" e4 v! T; S+ Y
递归思维要点' R3 V) I( ^6 v- _
1. **信任递归**:假设子问题已经解决,专注当前层逻辑 + _" A+ |$ u* f) d' b* F! i1 s6 W2. **栈结构**:每次调用都会创建新的栈帧(内存空间) * |5 X, K* y8 y2 ]6 x- H3. **递推过程**:不断向下分解问题(递)) m, G4 o6 ]9 V/ Q: V
4. **回溯过程**:组合子问题结果返回(归)/ M1 M) d5 W3 f4 g, T
1 Z4 Y9 N% ^7 v' T' T 注意事项# f5 X; R2 D0 Z9 g
必须要有终止条件 - U4 q: Z! j9 I递归深度过大可能导致栈溢出(Python默认递归深度约1000层)6 g- |2 A; H# ~4 w8 q+ l
某些问题用递归更直观(如树遍历),但效率可能不如迭代 : _" `) I; D, W尾递归优化可以提升效率(但Python不支持) 8 l1 m$ t" K8 I1 ^% C. Q! R+ z ; t, B# P- b5 I( m 递归 vs 迭代 1 N: h. G$ ~: u& T( k, S) ?| | 递归 | 迭代 | : Q' L P u8 u* l( h9 n|----------|-----------------------------|------------------| 9 R# ] [+ W. a| 实现方式 | 函数自调用 | 循环结构 | 0 S# A4 a1 v9 S: k| 内存消耗 | 需要维护调用栈(可能溢出) | 通常更节省内存 |; `% s+ U& Q" {) {( F/ `3 M x
| 代码可读性 | 对符合递归思维的问题更直观 | 线性流程更直接 |' y' X& ?5 F6 {2 U+ f; B2 S
| 适用场景 | 树结构、分治算法、回溯问题等 | 简单重复操作 | ; S9 o5 \7 r v" E y& Z9 A5 G5 e8 M/ J3 p/ o& h6 _ 经典递归应用场景 ) ]+ j1 K5 `, Y5 r1 n7 R2 G1 f1. 文件系统遍历(目录树结构)2 o9 N9 H( O3 S4 I3 x1 o
2. 快速排序/归并排序算法 % _! [7 I! V( P3. 汉诺塔问题$ j6 t4 } D! [9 v
4. 二叉树遍历(前序/中序/后序) 0 ]9 E1 c6 `" z2 K5. 生成所有可能的组合(回溯算法) 5 z1 G/ |' V' h w ^9 N- `4 M/ e$ |" \& m# R
试着用递归思维想象:你站在一面镜子前,镜子里有无数个逐渐变小的你在照镜子,这就是递归的直观体现。但记住每个"分身"最终都要有结束的时刻,这就是基线条件的重要性。作者: testjhy 时间: 2025-1-30 00:07
挺好,递归思维要点与我能够回忆起来我当时写递归程序的思路很一致,,或者被它唤醒,8 k0 l( ^' c" A6 M: j
我推理机的核心算法应该是二叉树遍历的变种。( `' D! U6 ~! @: H6 k: m
另外知识系统的推理机搜索深度(递归深度)并不长,没有超过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: + t I, k' E% }Key Idea of Recursion$ w, _( [0 E2 C. l$ S
) U/ i `% g4 f7 x r( U8 E. J# gA recursive function solves a problem by: / ^" @7 s3 W& y B) Y" v ' c/ \. F8 H x: ], x( V Breaking the problem into smaller instances of the same problem. K; O0 `$ g& U" Q& |* s
) }, r1 Z; g. `) r; i4 Q; r% h Solving the smallest instance directly (base case).% G8 L. M; ~ G+ n
+ ~- K8 a7 O4 c. c Combining the results of smaller instances to solve the larger problem. ! t( ], q+ b2 V+ L # W1 f9 V% M: h# v' V4 CComponents of a Recursive Function 9 y! ?4 [' F3 @8 @. Z! V$ k! W: e% A. D
Base Case: ! b5 {7 c# ]" j( C9 ~/ u* ^3 [- [" Z* y4 ]4 u
This is the simplest, smallest instance of the problem that can be solved directly without further recursion.; w; I+ S3 I4 T% c q/ T: M+ ^
. T) _" a& D7 \ It acts as the stopping condition to prevent infinite recursion.. r7 C% n3 D& w9 X$ Y2 r" B; r7 {
- E# o4 d( b* L3 b o3 v1 H# c Example: In calculating the factorial of a number, the base case is factorial(0) = 1.- {0 M C8 {# \( p
* p" v/ @+ G; P) O, e Recursive Case: ( `# C- ]7 ?& _/ ]& ]8 d! Y/ C2 o( D2 P, k" c
This is where the function calls itself with a smaller or simpler version of the problem. [2 t* r% F% x# L4 }$ x3 G/ S2 \) \
Example: For factorial, the recursive case is factorial(n) = n * factorial(n-1). % e5 j+ B; s- ?' d0 \0 c1 k# Q* H) W1 [2 C H# y `7 E0 ]
Example: Factorial Calculation7 f( r( L4 B- ?& }, d
( q- s& s e& l6 C3 v8 E1 O- U: |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: & A) ~8 ^, F: V5 ?! e + _- B- `2 ?0 D2 Q* e) ]4 I3 v Base case: 0! = 1 ! V! ?1 I: y' e+ T / J, ~9 O+ r- u9 H9 f Recursive case: n! = n * (n-1)!/ _, j4 Z7 U7 E( h
) a7 u! ]2 ^+ d: @
Here’s how it looks in code (Python): 8 D4 r" ]: z# j" I$ p* Vpython' x# d4 n3 m& T* n6 {
6 Z7 z) c" {8 O4 G0 ^' ^2 z5 y5 s" h8 e( }) R% U$ V& }
def factorial(n): / K1 C9 A0 D& p b/ X* `/ ?, {5 S # Base case R+ U& K/ e" E" x
if n == 0: , ]+ d+ Q7 r0 b$ u; Y: B( P return 1 8 f3 {9 P, }( y, l% O9 X! i2 a # Recursive case: Y! K7 d5 }1 t; T$ ^( ]# |0 L
else: 2 O, J2 F0 l8 d return n * factorial(n - 1) 6 C% x* X4 V- y" m) n , G! C$ E* J( i6 Z8 O# Example usage2 f2 B; i& Y' |4 h! F% p; ], Y
print(factorial(5)) # Output: 120 9 f# A, ~1 G/ a0 D# m" i 1 e0 D; H& {) T( QHow Recursion Works % V- S1 T( C% l7 E3 P 5 L* o3 l; l4 O+ O The function keeps calling itself with smaller inputs until it reaches the base case.6 H4 I9 Z, h z5 C" s
, @4 A. P! q: s- ^1 ]/ [ A Once the base case is reached, the function starts returning values back up the call stack. ( A `8 H; D9 \/ J! Q4 ^7 c/ L& v" k, C9 k: S5 z
These returned values are combined to produce the final result. 2 C& m% F7 E ?2 o" i$ Q0 @) c$ ~ , e! s, T9 f: V( d& m4 m2 GFor factorial(5): 7 q2 t% e- B! S- X( q% z ! B& c( S7 C3 \ L: d9 V( y& u e) G
factorial(5) = 5 * factorial(4) ; C- C" N6 w9 K: ?6 A# J' u/ qfactorial(4) = 4 * factorial(3)% g% d. D$ d. |% n1 C
factorial(3) = 3 * factorial(2) 9 [: J& X/ `. v" x" `factorial(2) = 2 * factorial(1)+ B0 J' |8 B; f% _
factorial(1) = 1 * factorial(0)4 n i5 p! L3 ?' R( c, p I& s5 ]! U
factorial(0) = 1 # Base case 1 ~0 S2 b" i D/ s% e" ~& E: n+ D( B3 Y5 M/ `! n4 G
Then, the results are combined:! c1 {8 w3 P: r( `
. ^% b& x" N6 v' n/ I' l- y+ }5 k1 U4 b8 x# \ S; J
factorial(1) = 1 * 1 = 1 6 v: c* Z& g4 _2 M t' V( qfactorial(2) = 2 * 1 = 2 ; u& }5 ~0 H! _9 Z6 r8 R- _# t7 Pfactorial(3) = 3 * 2 = 6. e+ P7 {% }+ U" X7 s& `
factorial(4) = 4 * 6 = 24* E- E% j | q" `: ~6 @/ e
factorial(5) = 5 * 24 = 1206 y: m+ i2 S2 V+ u. ]
% r# a9 h+ K+ Y9 i5 X: l
Advantages of Recursion 2 v) F' v& S u! D) E/ J 2 s9 k) J. x4 Y/ F/ v 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). 5 |1 q) v/ f8 F1 j! h* n* L2 Q% q! o j1 P3 k! r$ ^% |0 w
Readability: Recursive code can be more readable and concise compared to iterative solutions.. g' b' ~, H6 ~
$ |5 ?* J5 q7 y0 J+ Q$ Z
Disadvantages of Recursion. `' F* i' H' L% B4 O
3 B0 D7 j, y+ q" M6 i' l 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. ) D- I7 p5 Z/ L. l) {! e ( ]5 F" R' l* p: `$ q3 r; E Inefficiency: Some problems can be solved more efficiently using iteration (e.g., Fibonacci sequence without memoization). 1 I: {! p3 J* {; P. O, ^& t ' l) D: z c. }! I3 {When to Use Recursion1 s6 {" n1 Y! p: r' T
8 F5 q, Q9 [. [9 j, v( [
Problems that can be broken down into smaller, similar subproblems (e.g., tree traversals, sorting algorithms like quicksort and mergesort).+ c' A: @2 \, b
4 m9 r! ]) S5 h* S% k1 T
Problems with a clear base case and recursive case.$ [/ k# [7 o8 i' }! ~/ R0 Z5 D+ \7 P
7 S- S5 M1 w! i6 ?( xExample: Fibonacci Sequence- v! d" Y) R$ ^9 G
7 { w# k. `: e/ Q
The Fibonacci sequence is another classic example of recursion. Each number is the sum of the two preceding ones:+ u5 P8 g5 X4 z
# {3 O% V* H0 M, W( s. a' f/ }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)./ u, [3 |/ E, r" W- _
8 D1 o9 ^3 ?0 u9 p V% n! t# \& UIn 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 现在的开发流程,让一个老同志复习复习,快忘光了。