1 O5 s% O3 t4 w2 k 关键要素 2 l( B# U( ~: L! H( w5 i; s3 \1. **基线条件(Base Case)** 9 J( b/ S# m! A; D) V8 g7 ] - 递归终止的条件,防止无限循环 # K! B) v* E6 S, W, n9 H - 例如:计算阶乘时 n == 0 或 n == 1 时返回 1- I5 U, f% U7 ?
@7 E0 q* G) v; N" v3 E% p2. **递归条件(Recursive Case)** " K# ~/ _7 o- N5 z8 w9 n7 w7 A- h - 将原问题分解为更小的子问题. ?) b/ p% N! k6 _/ K
- 例如:n! = n × (n-1)! 9 J& Y0 A: M+ R4 e - K7 e' T' i& _* n4 Y 经典示例:计算阶乘 1 V5 B5 V" A* |' X! L# c8 N/ opython5 G* P' ~+ Y2 }" b) y9 u
def factorial(n):6 P& T: s% z4 R' }. x
if n == 0: # 基线条件 7 t6 d) P$ Y1 M! z* r2 `7 k return 1 8 Z: ~* `2 Q# p! r else: # 递归条件% k9 z7 a/ |7 [1 ]
return n * factorial(n-1) - h' k) k: S+ [执行过程(以计算 3! 为例):5 t6 F2 k* r h' [4 M2 a
factorial(3) # T% D5 R/ a& r& p9 n6 O3 * factorial(2)2 U. ~2 L& h* I2 ?8 x- s( h2 I* J
3 * (2 * factorial(1))7 g/ m `* A+ L+ @6 b
3 * (2 * (1 * factorial(0)))/ v6 L& l. N4 B0 \8 W& s5 t. c; R
3 * (2 * (1 * 1)) = 6 0 [: v/ x3 v! ?, n7 y$ U % A- C) K: u) Z. }* l# e$ a 递归思维要点 " U0 C3 [7 P) D1. **信任递归**:假设子问题已经解决,专注当前层逻辑 0 |" p1 P" T, M# {$ G2. **栈结构**:每次调用都会创建新的栈帧(内存空间)4 [) X4 g8 T* U
3. **递推过程**:不断向下分解问题(递) # Q: O% _. x% G4 r8 Y p% i4. **回溯过程**:组合子问题结果返回(归) ) m9 G, z- u0 R; Z5 s5 E- I7 i" M6 N' d' t$ N! k
注意事项' w" y$ L; e/ S/ u, O
必须要有终止条件 0 |7 B V4 X) [% p9 E递归深度过大可能导致栈溢出(Python默认递归深度约1000层)8 w: ~5 J, s& K3 ?' D) k& o0 U
某些问题用递归更直观(如树遍历),但效率可能不如迭代 " O# b& N# a9 c: [3 _! X尾递归优化可以提升效率(但Python不支持) $ v4 x) ?8 Q$ I0 q 8 p# h# f, v( g! d6 `% z 递归 vs 迭代: G/ W$ v0 |5 o. U0 d/ B9 g7 M
| | 递归 | 迭代 |; K/ R) K+ T( A, V
|----------|-----------------------------|------------------|# I7 Z1 G# Q5 I1 \8 Q& r, P2 P
| 实现方式 | 函数自调用 | 循环结构 |9 I& F" E: z! _
| 内存消耗 | 需要维护调用栈(可能溢出) | 通常更节省内存 | 3 }$ }3 v* g8 y0 `% u8 Z| 代码可读性 | 对符合递归思维的问题更直观 | 线性流程更直接 |* ~$ X# s; N! \- ~' _
| 适用场景 | 树结构、分治算法、回溯问题等 | 简单重复操作 |( Z' D# a' V8 ?& W4 w% q; Y& }
! Q) U% _9 z9 Q5 V: T9 F+ X# ?) E
经典递归应用场景 : w% D* C& p' y4 V# k1. 文件系统遍历(目录树结构) , P; Q: A y4 F U/ V2. 快速排序/归并排序算法 1 p" c$ A7 a Y3. 汉诺塔问题 ( D' q+ y' E, z1 e4 v3 \ V) Z+ E4. 二叉树遍历(前序/中序/后序)! S1 h |% ?4 U J; [2 Z
5. 生成所有可能的组合(回溯算法) . E/ y' I" ]- V4 S- T7 q( P: t1 o7 p2 E% i: M. n
试着用递归思维想象:你站在一面镜子前,镜子里有无数个逐渐变小的你在照镜子,这就是递归的直观体现。但记住每个"分身"最终都要有结束的时刻,这就是基线条件的重要性。作者: testjhy 时间: 2025-1-30 00:07
挺好,递归思维要点与我能够回忆起来我当时写递归程序的思路很一致,,或者被它唤醒,# _/ I" F/ E& X, Z4 S; g! o) j
我推理机的核心算法应该是二叉树遍历的变种。0 |$ h$ p; }$ C! u) t
另外知识系统的推理机搜索深度(递归深度)并不长,没有超过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:+ v- a3 P7 Y* D$ t6 o9 L- p, a
Key Idea of Recursion) z2 J! n' u1 I7 z) j5 @8 l9 q
% W! P3 R# x( q
A recursive function solves a problem by: 1 q& u+ P, O$ o+ O , E* ]2 J+ I6 J I; r6 F" w8 I Breaking the problem into smaller instances of the same problem.4 M% U) b/ Y1 Q4 H( V
, N3 f1 n) `" s% |: e# }- J( Q j! N
Solving the smallest instance directly (base case). * Q7 N6 f5 z' ~) @3 O+ q+ G1 e3 Q
Combining the results of smaller instances to solve the larger problem.3 h7 z5 R) U2 Q8 O0 [7 x4 @/ J4 j
# \' e* l) `7 v/ r8 V+ q
Components of a Recursive Function " f( U9 u2 z$ z/ ^; K; R * u2 ~/ Z; C* M3 a" J J Base Case: , f, a7 E7 Z; ~+ ~* _. k 3 U7 ~3 h* ^; B5 s* y This is the simplest, smallest instance of the problem that can be solved directly without further recursion. , K G$ G6 u/ V/ h+ J) g/ [) H 2 K7 z7 H4 v1 g It acts as the stopping condition to prevent infinite recursion. ' E5 G- m ?1 x/ u W7 w 8 Z$ L+ E! L$ `# x% D Example: In calculating the factorial of a number, the base case is factorial(0) = 1.- f' o# M) t/ t; p
: T! x' R: `4 ?& ]1 a- a. O7 b Recursive Case:6 k9 `3 N) J2 R3 g& @4 d7 G) f
$ _. K0 X1 h% |1 w' v3 E7 j. t" k
This is where the function calls itself with a smaller or simpler version of the problem. 1 M/ P9 P! W# E$ |1 ?$ Q& j - y6 }% w% t5 u. S) e% s" G/ X4 T Example: For factorial, the recursive case is factorial(n) = n * factorial(n-1).0 _. `; i* n% G8 s
. y- g3 ~2 L. M/ X4 v3 Y* ~/ e- Y
Example: Factorial Calculation N/ o& r& r4 E2 _: W+ L
8 {% |3 `; N2 Q1 ~% kThe 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:7 Y1 Z4 z! ?: e9 M. w
" a- g' Q# a. P' s! _ Base case: 0! = 16 s- _! }! R" t
6 P, P+ q8 P% G' _6 }7 W6 R7 Y' g
Recursive case: n! = n * (n-1)! ) ~. m) G) P& r+ o& {$ m) X, {# K! J+ b. |$ c0 i$ w p; P
Here’s how it looks in code (Python): " K6 `6 v, x! x6 I ?( D( ~& Zpython 2 }' i @+ n1 c* J2 n' T) K 7 D0 _3 T1 a+ S9 N! y6 s7 ^ ' s& [4 `# M8 m9 j/ K0 ?2 Bdef factorial(n): q4 Z) y n# Y( E3 A # Base case 6 l0 q8 A7 R3 `" p5 R5 p& I if n == 0:+ _- y/ [4 }1 J3 x8 r. y
return 1 ; E. q; A& L3 m' L # Recursive case5 K$ J2 v/ o) W* c6 A2 H, c
else:% L' H6 e: _* x8 `+ b5 L
return n * factorial(n - 1)+ }/ p+ Z3 A, Z) b; c
& I9 i2 Y+ ]1 s" _$ `: O) r' G# Example usage " T ^" n5 M( H! O( gprint(factorial(5)) # Output: 120 G/ \- N; O7 ^+ v5 C
( _' ?5 q, J6 @& t( y4 s1 }
How Recursion Works 3 i, J1 t# p- C# s$ e: n4 a! G/ I* Z, j* i1 h- Q
The function keeps calling itself with smaller inputs until it reaches the base case. / {% i, h7 a& r# b) x 2 @& ^6 C+ ]( }& d Once the base case is reached, the function starts returning values back up the call stack.- g: b/ K+ h T% r4 \& o4 h
, s9 B# ^* A: O) x( L
These returned values are combined to produce the final result. 9 J0 b; I. z5 g* t* a) @3 N ' G9 `. ~/ b: F+ I4 L8 B' UFor factorial(5):2 l* z1 v/ q$ i3 [ E* F9 R
6 w! I2 ~' I8 B! B
7 b8 s5 k" e0 L1 X2 c `" C
factorial(5) = 5 * factorial(4)* q$ B# @2 H" j/ B7 i9 w% |7 V, D
factorial(4) = 4 * factorial(3); n' ]; e$ e) r* V& }! t1 n/ t
factorial(3) = 3 * factorial(2) 5 k; l& s: ?5 V4 ]; h$ Qfactorial(2) = 2 * factorial(1) ( e- @; y K% a5 E ?- E; l& ffactorial(1) = 1 * factorial(0); ~/ o2 M' ?$ v8 o0 P
factorial(0) = 1 # Base case9 L0 w h7 B( b3 n' E% ~
( K0 \" q* E" H( t) Y DThen, the results are combined: - P! s0 a6 o) h+ q% E 1 O/ V- C$ d+ f9 h! Y: \. t: ^1 ]& p0 U% u, v
factorial(1) = 1 * 1 = 14 i( ]: w5 ~+ M8 O! ]9 @8 y2 @# @
factorial(2) = 2 * 1 = 2$ w' r. A! _: |3 o1 h/ [' Q
factorial(3) = 3 * 2 = 69 o) x) q8 }, g$ J# C" G+ O/ K
factorial(4) = 4 * 6 = 243 e1 I r: \0 v' O6 e! j, x
factorial(5) = 5 * 24 = 120 # a/ O, v; o" P7 V# h) E4 y* { + I3 z% a7 s3 n( Z- n$ `5 G7 p$ ZAdvantages of Recursion( M$ f/ [7 |4 I" L1 L
/ k/ ]$ V8 y2 ]: Q+ Z8 h; L
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). - S% J9 O8 }& v& Q1 l) p+ F6 k" {! M# k1 U$ C0 r3 `# d
Readability: Recursive code can be more readable and concise compared to iterative solutions. # p' B4 \4 _: Y( x* E0 Q 3 b$ p7 e- w' i( T9 [0 KDisadvantages of Recursion* o0 ]; f% c4 H' X
M- d2 ^% [- p* K
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. 1 Z W# B" I" h7 g! ~& _ O4 z3 {- M
Inefficiency: Some problems can be solved more efficiently using iteration (e.g., Fibonacci sequence without memoization). . ?8 L0 f' n( E7 g2 K5 D0 n7 F& X5 D: Z" N" W/ \& T# @" m7 g( x3 y
When to Use Recursion K% h3 R$ m( r1 u) s6 q# N8 ]
# i" D+ _7 F6 x( \& M Problems that can be broken down into smaller, similar subproblems (e.g., tree traversals, sorting algorithms like quicksort and mergesort). * |$ k3 ] k8 Y7 S* n) P8 Z5 j' x( k& V& p# s8 t" p
Problems with a clear base case and recursive case. / w7 x, Y! {" d! L8 P/ {! q, J8 f, k' [, d& ~! C3 `) F* e- h" R0 x
Example: Fibonacci Sequence( a8 E# J- y' U! ^: x2 O" c/ O
) g" d; C) y: T6 w
The Fibonacci sequence is another classic example of recursion. Each number is the sum of the two preceding ones:. p4 p( Y. R* U& m; D
: S# @# N( v5 w, v! t$ G* L% y
Base case: fib(0) = 0, fib(1) = 1 & J, B3 F) K; [; \1 t 7 K- F" K; v6 O) [% M Recursive case: fib(n) = fib(n-1) + fib(n-2) d. \7 D3 T( Z" t; i+ F: B - B0 q! h0 t9 `! f9 B+ i8 apython6 ` e+ i3 F# p3 j$ {1 f
3 [2 N y+ i7 h4 u; S% }/ w; `/ ?' a
; h* F7 c2 k" |0 rdef fibonacci(n):4 _; n% j: T' s) S# r. e# z; p0 h
# Base cases5 g5 v, X1 A, J1 V$ x
if n == 0: 8 Y |* a$ ~6 Y return 0; S2 v2 D% F# y+ i
elif n == 1: ( S, L4 n. f2 w' f, f) y' o0 N return 1 1 I! u' Y/ U: N # Recursive case # E# [* u! m- o4 M0 z2 H b else: 8 ^! ] x7 u* ?: L0 F+ h4 q return fibonacci(n - 1) + fibonacci(n - 2)# W$ [% h. n1 E, D7 n/ F
+ H7 Z9 G9 v; Z0 h- B, ~4 V# Example usage( Z. Z U5 r9 _2 h+ m1 Y4 _
print(fibonacci(6)) # Output: 8 8 T5 n" j7 C6 X7 @) m: ?2 A1 \0 P 9 a8 T- k \8 vTail Recursion z/ O" _. t S- q
8 G% b7 s6 | ~. G- S( w% lTail 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). - g4 d) g( ^' e" w1 B" N+ m! H$ R% X' r& M6 v5 Y
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 现在的开发流程,让一个老同志复习复习,快忘光了。