: } t) Z4 \8 L( V' ]递归是一种通过将问题分解为更小的同类子问题来解决问题的方法。它的核心思想是:**函数直接或间接地调用自身**,直到满足终止条件。 ) H( `5 B& a9 H& S8 S d% F2 b- ?( P+ V 关键要素 5 N5 W3 j2 T; m, P1. **基线条件(Base Case)**9 q7 n0 f8 _: ?4 {5 v/ P
- 递归终止的条件,防止无限循环 2 i' \' G- K2 Z# C - 例如:计算阶乘时 n == 0 或 n == 1 时返回 1 . f/ u, `5 a4 E, X K+ c, `' G7 a9 J, A; Z6 U* p. W
2. **递归条件(Recursive Case)**4 f8 G! p# I* U1 C9 H- l" V
- 将原问题分解为更小的子问题- y3 }3 Z5 q) l4 D+ p& K
- 例如:n! = n × (n-1)! + j* W; `# `, y0 L6 n& n4 g6 J2 H# a5 }7 k; d) V
经典示例:计算阶乘 ; _9 N% _3 g6 F5 m$ D- F& @python 6 K7 M, W4 Z6 w; l1 q+ z, o7 Hdef factorial(n):; p* C( } z) i7 N6 q6 z' Q
if n == 0: # 基线条件 ; N: J \" @( Y& J return 1) f6 p1 T( L* D/ X
else: # 递归条件' |) R7 w- @" Q# P- y
return n * factorial(n-1) & w; e f( d* j( _& E( U3 i执行过程(以计算 3! 为例): H, @. f* J% A
factorial(3) v U7 h6 T8 s( t7 Y) @) |
3 * factorial(2)4 J. A0 d+ v. Z9 j) u* a
3 * (2 * factorial(1)) 9 F3 H9 b8 t; B0 k9 d3 * (2 * (1 * factorial(0))) $ c* Q' c$ m4 S8 U0 l1 F3 * (2 * (1 * 1)) = 6, T; L3 T6 v! j
' A- B5 r: u# N- N8 P7 A
递归思维要点2 i1 L3 G U/ f
1. **信任递归**:假设子问题已经解决,专注当前层逻辑1 h0 f+ r u/ z; o! g Y! B+ A
2. **栈结构**:每次调用都会创建新的栈帧(内存空间) 5 O- t2 c8 f1 h$ s9 t e) ?' ]3 C# }3. **递推过程**:不断向下分解问题(递) : ]1 i! n# n9 A, ]4. **回溯过程**:组合子问题结果返回(归)+ m4 R( Y: p6 H$ J* a0 K* D+ O9 I
; l" `/ Y* Q. T, [# y8 Q0 | 注意事项 4 ]9 r! {1 V8 ^, R3 ?+ n必须要有终止条件% \; K) M/ {. _4 X1 x8 a$ M9 \. V
递归深度过大可能导致栈溢出(Python默认递归深度约1000层)6 ^; N0 b f" V2 T, J
某些问题用递归更直观(如树遍历),但效率可能不如迭代, d" Y5 w" k, o8 r
尾递归优化可以提升效率(但Python不支持) 4 v2 c# Y4 L" f3 \, t1 a, z! c. j$ y: N9 ~
递归 vs 迭代; v4 Z$ H2 F$ K& D
| | 递归 | 迭代 | 3 r5 U/ i2 U/ k|----------|-----------------------------|------------------|2 g( a2 k1 r4 _2 Y/ d" X
| 实现方式 | 函数自调用 | 循环结构 | ) G+ k* t9 d$ @) K/ Y% V| 内存消耗 | 需要维护调用栈(可能溢出) | 通常更节省内存 | $ Z. w( f9 B/ ^' I, x# {| 代码可读性 | 对符合递归思维的问题更直观 | 线性流程更直接 |# i. _4 S5 H8 l) o! |$ v
| 适用场景 | 树结构、分治算法、回溯问题等 | 简单重复操作 |+ W9 e* e" Z+ m3 |
7 A- u+ m6 m5 ]& Q5 V& @- b8 G9 A$ ^
经典递归应用场景! C1 f- U3 A0 S2 g# Z) ? ~
1. 文件系统遍历(目录树结构) ) w8 \1 R$ q( `/ m, l; q2. 快速排序/归并排序算法 - \; f$ Z9 y# \8 e3. 汉诺塔问题, e8 v: F* r3 d( s$ h
4. 二叉树遍历(前序/中序/后序)6 |3 v! [2 w6 g! i
5. 生成所有可能的组合(回溯算法)6 E3 W# o/ m$ w* `
8 y+ T# F8 [# @6 l M5 M# v; d3 M
试着用递归思维想象:你站在一面镜子前,镜子里有无数个逐渐变小的你在照镜子,这就是递归的直观体现。但记住每个"分身"最终都要有结束的时刻,这就是基线条件的重要性。作者: testjhy 时间: 2025-1-30 00:07
挺好,递归思维要点与我能够回忆起来我当时写递归程序的思路很一致,,或者被它唤醒, . j# u# G. z% l, l我推理机的核心算法应该是二叉树遍历的变种。. n5 g5 Z2 w1 P5 c; |$ l. q5 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: ; U. Z6 ^) e) K4 P' B ?Key Idea of Recursion9 o- f) l! ?5 x2 N1 B. g/ t' b! F
& ~% D% `0 c$ J+ t* i, Y8 gA recursive function solves a problem by: 7 ~# f s! ]/ ]5 X8 S$ [* r9 X2 U8 X4 H7 F2 X7 U$ V
Breaking the problem into smaller instances of the same problem. : }1 e* R8 u+ C! F) ^ ! l) ]7 x9 T7 h, v; J Solving the smallest instance directly (base case).* k+ \1 Y" x# B m8 S8 |
8 K4 u# h) A- v2 D) O! |2 K
Combining the results of smaller instances to solve the larger problem. * u* N1 ^' n; z1 j3 B+ r4 h. ^; e/ m) }& l& H
Components of a Recursive Function 9 z" `. h" C. F2 v- V/ x 9 K9 S8 w3 e# q& u9 H6 V7 y Base Case: ! `) d d @, i9 r9 m& H& y1 k& ~) \6 ~/ y4 m* W
This is the simplest, smallest instance of the problem that can be solved directly without further recursion. 4 Y* \% ?' G6 U' i% C4 B6 A% H ) O4 [8 J# y) n7 M# u6 D% s' v It acts as the stopping condition to prevent infinite recursion. 7 C, f! {7 r# S. v ; l8 w- W2 Q5 m) t3 N D Example: In calculating the factorial of a number, the base case is factorial(0) = 1. . V! F5 M. l; r# B1 `0 Y " F$ f8 f2 c7 k4 B# {: M2 W* H' y Recursive Case: " z, G1 P: \% }2 w1 |1 J ! M N7 x% d8 U, @. \9 j0 c) u, V This is where the function calls itself with a smaller or simpler version of the problem. % m; M2 j, a/ d$ \, R; G( B/ y' L% H; Z& S* Q) t3 I5 X y
Example: For factorial, the recursive case is factorial(n) = n * factorial(n-1)./ x$ i! X* R% R7 f5 }
( i ~6 r( e0 k: x6 h" a
Example: Factorial Calculation' Q: ?+ i9 L& s/ x# e
' }1 m- ?: Q$ Y1 Y+ U ^9 MThe 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:* u5 Z+ B* E! F0 M4 i. u) T
! n$ g* y+ ~: f" g1 g Base case: 0! = 1 & u5 }' Z- s. R1 k! |# ~9 ?3 L* o1 T
Recursive case: n! = n * (n-1)! 7 ~, n# C9 M* ~9 Y7 q* o ; `9 @3 }# v) NHere’s how it looks in code (Python): . O. ]& T# L" k4 s! M7 z3 npython) Z+ N: b0 }4 Z W1 D0 x% V- B
) u4 b6 _0 e+ j% M% ], \; ?: r" ]1 ^1 s- X
def factorial(n): & }) v' i, c% r) Z7 z; E( A # Base case% O* m: `. o* v
if n == 0:0 _: C1 V& Y" I8 d7 P0 ?
return 17 n$ w* D( m" \, i2 H/ H; q
# Recursive case' a! H r" ~. Z% Q9 z# k( a6 r
else:, k8 G0 F. z+ @ y- i
return n * factorial(n - 1)9 J4 N A6 v: v' W/ z
0 w" L6 x" C+ u- T$ x) B$ ~4 U
# Example usage, v8 ~( A! Y8 f8 B# P' u
print(factorial(5)) # Output: 120 ( |7 |; n$ c8 I $ Z& R' Y2 }6 Q/ i) @; Z7 hHow Recursion Works o8 q3 i1 M4 Q+ @6 D1 G
' l# l3 R2 T% T7 X
The function keeps calling itself with smaller inputs until it reaches the base case.( y, l0 o2 @; ~3 A# P
1 G r0 Q- V9 }# F; k" u+ d: ]
Once the base case is reached, the function starts returning values back up the call stack.6 f& _3 p& _, v5 t- p8 B% w
' d4 \+ q( P) ? These returned values are combined to produce the final result.; m! |, z% T% T& Q! |& n" p
% N- R- t# f2 M0 x8 d
For factorial(5): ( G5 g8 ~6 Y1 v* v6 {" S, A+ ~' M2 T1 Q, o
8 v" {4 I0 U6 L2 k2 }
factorial(5) = 5 * factorial(4) . F& g. ?* B$ Zfactorial(4) = 4 * factorial(3) : U) i5 _6 y9 I: j$ kfactorial(3) = 3 * factorial(2) 3 B* ?1 L- s& e9 N4 S. ofactorial(2) = 2 * factorial(1) 5 V* _6 G$ E9 c. F- T# zfactorial(1) = 1 * factorial(0)+ g6 b. }6 {" l9 f2 k
factorial(0) = 1 # Base case$ T; h( S* N# U. u) X: I- ^' Y, n
! j7 `2 u/ ~$ V3 ]/ D$ NThen, the results are combined:% P1 h! u3 V, `; R2 I
* p/ g2 N' m# \( [' f
( d9 D5 @; {6 Q# d3 n% R
factorial(1) = 1 * 1 = 1, n" l$ l' i4 k" D* h9 c$ Q# |
factorial(2) = 2 * 1 = 2 " H% `0 b% O2 I" ~) Sfactorial(3) = 3 * 2 = 6 0 s; _: _8 h5 C' H" o* h2 |0 Yfactorial(4) = 4 * 6 = 24 0 K& e' e/ J; w& X" ?$ R# P& xfactorial(5) = 5 * 24 = 120 / a6 E7 X X+ @% ?' e& X" ]# C% B 8 D6 ^0 A& Q; @# Z7 f6 y$ `, P% OAdvantages of Recursion O) C7 C3 A6 L$ X g( ?% B K' e# Y
% J4 j& G8 G9 { n8 b 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).% I8 q: @2 Q n0 q5 b: N3 B
4 E; X) G+ S7 ~( X
Readability: Recursive code can be more readable and concise compared to iterative solutions. 1 r8 x. A: i2 a4 {4 N6 h8 P6 m5 z. f3 B* v- \ }2 N7 L
Disadvantages of Recursion ( Z) T$ q+ J4 k% B, |6 P. m; K8 R: t. `
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.4 E5 f8 ?$ F( }4 K- G0 U
) f, B2 I$ Q/ }6 m
Inefficiency: Some problems can be solved more efficiently using iteration (e.g., Fibonacci sequence without memoization).8 g# t4 o4 g: t
% K+ w1 F1 m8 y* wWhen to Use Recursion 2 t4 A% L- M: e: C0 c" n/ X+ o; Z5 y- x. p. Q3 W8 ~7 i: `* ?
Problems that can be broken down into smaller, similar subproblems (e.g., tree traversals, sorting algorithms like quicksort and mergesort). " p" ?- D- |( b" ^1 [- _! k8 |- R# R$ D2 [7 H
Problems with a clear base case and recursive case. " ~: }# n! E. \2 _/ Y4 J 9 z9 h' h; X3 }) ?/ C; L$ eExample: Fibonacci Sequence ) k. U3 x/ L$ B; u5 K* X1 ?# L. e5 h' h
The Fibonacci sequence is another classic example of recursion. Each number is the sum of the two preceding ones:2 h4 e2 C+ ^( C
% T& v1 N% E I0 ]. e! l, L$ m1 x Base case: fib(0) = 0, fib(1) = 1 % h7 u1 I: {8 f0 F 9 w1 O1 ]/ u# k: { Recursive case: fib(n) = fib(n-1) + fib(n-2)) ?- m- G2 X+ E2 P3 X8 u
; b7 f- F; t1 i% H0 v
python! O. t& E& M8 i8 W7 z
/ J6 P& o0 v7 T& n# |8 q % {9 E9 P2 h* t' ydef fibonacci(n): ) [/ B. ^$ j( d # Base cases' q$ U% z7 \' f) ]- X7 h) v- t( l
if n == 0: 8 t- y0 v$ I% y, Z! i* F, l return 0 0 Y1 X/ b' D6 B elif n == 1: ; ]9 x. y' c1 @$ i/ g9 q return 1 o: I) G* G! R. `( @# ^ # Recursive case * k1 y/ ]/ r V6 h- j else:: n$ \% a: s! S9 A; \
return fibonacci(n - 1) + fibonacci(n - 2)% P. Q6 a: [/ ^6 F" G
$ t: K, M! [. s( G. h5 v# Example usage 2 o& m, p0 }1 Y. ^( Pprint(fibonacci(6)) # Output: 81 l& |/ n8 n. u4 |( A
7 w# y1 ~ P/ Z9 \, L1 i! |0 C; aTail Recursion i9 }+ {4 Q, D" B
o6 W9 u! C) C. J2 w! T2 G( mTail 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). * i5 S4 I+ w$ [$ g/ v 8 W8 }- }1 j3 {* T8 YIn 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 现在的开发流程,让一个老同志复习复习,快忘光了。