6 W) O. e6 D, N! R$ n解释的不错5 S7 Q2 w6 q3 e3 ?; O2 d1 J
3 z9 W1 Y3 e. e S
递归是一种通过将问题分解为更小的同类子问题来解决问题的方法。它的核心思想是:**函数直接或间接地调用自身**,直到满足终止条件。 4 ?" ?# i- ?4 }1 j% N3 l 4 l3 C7 `* _& G, B3 n 关键要素4 D* w- q3 \" d, \, v
1. **基线条件(Base Case)**5 x: W" D+ W, J" `2 Z0 x2 u
- 递归终止的条件,防止无限循环 + Y" I, L( h, y# Y- H8 W - 例如:计算阶乘时 n == 0 或 n == 1 时返回 1 x8 F7 Q# ]3 Q" u. ^; d2 g X
2. **递归条件(Recursive Case)** 0 n+ T0 H) k! A1 p! m - 将原问题分解为更小的子问题6 c d$ E+ l; f+ ]& _, u6 }$ Y
- 例如:n! = n × (n-1)!* Z$ [! [9 x& u, D; \1 V
6 x4 ?7 @2 E X* U( T/ w: @ 经典示例:计算阶乘. ~! `2 X5 Z2 h' [3 P
python `8 g) p0 V& p& _2 y( o: \3 Mdef factorial(n):' H2 f: S! X% [- _& u
if n == 0: # 基线条件& ]0 w' b/ L+ y3 Z2 u! E/ Y% M8 H
return 1+ a) w: r2 J. L& d
else: # 递归条件 v+ ~0 M: f5 \7 m: x return n * factorial(n-1) 0 U% F6 v- I9 o- @# c, j执行过程(以计算 3! 为例):. m: X8 _" f0 c7 w) [9 G
factorial(3)9 h$ u: L3 B" g0 S
3 * factorial(2) % f5 \( o: P4 |. i3 * (2 * factorial(1)) . L* i, \" z0 c8 m2 H, z5 ~5 l3 * (2 * (1 * factorial(0))) 5 M ]( ^) ? H3 * (2 * (1 * 1)) = 6- Q" _& P9 r7 E9 Z2 t' d s
# B9 C9 Y( j: D; P7 M* ?2 ^! J- z
递归思维要点: N9 U4 v1 b9 c' f( G
1. **信任递归**:假设子问题已经解决,专注当前层逻辑 A3 W8 U$ x2 [2 a% \, ^2. **栈结构**:每次调用都会创建新的栈帧(内存空间) : {2 H7 D0 p( J( \6 c3. **递推过程**:不断向下分解问题(递) 7 s8 }* r' K5 e3 k7 _- ^3 [2 W4. **回溯过程**:组合子问题结果返回(归)8 X U+ f4 b! g6 b' L! X
+ V( W* a j3 s% F 注意事项 ; E2 v4 U, r8 H( c必须要有终止条件 * k1 h% H* M ~$ Z0 Z8 s递归深度过大可能导致栈溢出(Python默认递归深度约1000层), N2 r. Q2 u5 X0 [
某些问题用递归更直观(如树遍历),但效率可能不如迭代$ _& ?" _8 r" l3 \- o7 z
尾递归优化可以提升效率(但Python不支持) & l$ a9 e2 c* J# ^$ ~( Z) D7 a! N, [: u' [ W
递归 vs 迭代( ]$ B: E8 w7 z c+ {6 z- u
| | 递归 | 迭代 |$ z* u+ X- h* v0 m( y ?" [
|----------|-----------------------------|------------------| 3 b8 `* u0 j! ?& t+ |& t' || 实现方式 | 函数自调用 | 循环结构 | . U' \+ W3 ^" t2 S| 内存消耗 | 需要维护调用栈(可能溢出) | 通常更节省内存 | 6 b8 u3 b2 O- |8 {2 Y( A* ~( A p| 代码可读性 | 对符合递归思维的问题更直观 | 线性流程更直接 | : e* l3 M: e6 L" ~" t8 h2 b| 适用场景 | 树结构、分治算法、回溯问题等 | 简单重复操作 |4 a% B% ^( }* `' M) m
# b# f: X1 u8 Q( n5 t5 l: u
经典递归应用场景 / X+ Q, ^; j b7 h3 U1. 文件系统遍历(目录树结构)6 S" J6 ]7 j0 E( }
2. 快速排序/归并排序算法 5 |5 b3 ]- {: ]. f" a9 a. F1 P3. 汉诺塔问题4 h0 O' l* P0 `. {7 c4 K
4. 二叉树遍历(前序/中序/后序)% G5 ]5 o$ T k/ Z
5. 生成所有可能的组合(回溯算法) % K: d% ^& r/ [) y$ o) s8 K/ z& ~, ]% n N
试着用递归思维想象:你站在一面镜子前,镜子里有无数个逐渐变小的你在照镜子,这就是递归的直观体现。但记住每个"分身"最终都要有结束的时刻,这就是基线条件的重要性。作者: testjhy 时间: 2025-1-30 00:07
挺好,递归思维要点与我能够回忆起来我当时写递归程序的思路很一致,,或者被它唤醒,- s+ _- [" a$ X
我推理机的核心算法应该是二叉树遍历的变种。 , X" L$ [% a& i. l另外知识系统的推理机搜索深度(递归深度)并不长,没有超过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:4 R' X- n: i% P
Key Idea of Recursion ( E$ t: D. g+ z8 n0 ^0 }9 J$ {2 o1 w+ m) A. j
A recursive function solves a problem by: 0 B' p2 K* U- j' O. A* u& w: J' F2 k( h5 S" `1 q& g6 z
Breaking the problem into smaller instances of the same problem. % K& g6 ^8 G- F1 s. r( w1 `( U, ?5 ]: K, V$ P7 P3 d3 i6 H5 H Y
Solving the smallest instance directly (base case). % h9 F) c3 M x- B( ~0 T- B 2 p1 H5 q$ ~- U2 i Combining the results of smaller instances to solve the larger problem./ h: c! D! B- _
4 e [. K, V. W; W v" p% J$ HComponents of a Recursive Function - J" C6 V" ~" T. R4 t$ w0 a8 w2 u Z$ n" ^
Base Case: * M. v2 n+ i0 R; L1 D & _5 K" z% }5 b$ h4 ]8 L This is the simplest, smallest instance of the problem that can be solved directly without further recursion.* b: ^6 Y' X0 s% T5 w' c
0 C( {3 ^% g( c" f It acts as the stopping condition to prevent infinite recursion.2 K" H4 g: u; `$ h
. c/ L( C2 a" O/ W0 ~. O3 d3 C4 |/ m
Example: In calculating the factorial of a number, the base case is factorial(0) = 1.; p; G# M" E4 D
/ r8 Q$ V8 b0 u! M Recursive Case:9 \( e; t+ g1 N, e2 W) n% c
G) m1 f& Q* N$ r, T- m This is where the function calls itself with a smaller or simpler version of the problem.) a$ _. z! P* I: S; S/ U
' }. U, Q2 z: H: I0 g Example: For factorial, the recursive case is factorial(n) = n * factorial(n-1).; ]! p+ h" Q3 S8 q& E
3 ]3 }+ B* \. j" m9 IExample: Factorial Calculation' }9 Z3 I' m* d D7 J) g4 @. n8 h
; I4 m, Z; M6 G; U! m, F( 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: 5 ? U+ a2 \" c * a$ _* ^4 c% I Base case: 0! = 1 9 \. u. V9 [9 }& q8 ~/ P$ U0 ^$ O! e- [# d" e
Recursive case: n! = n * (n-1)! ! e) X! m# I; W' Q1 p& K4 r6 u' d3 A/ g }( K0 i! L0 i4 S
Here’s how it looks in code (Python): & r& ]9 i: g5 g/ lpython 4 h+ v1 J1 B$ b- W # p0 b3 x; {/ q- ~/ v [9 C! ]6 W4 H7 m
def factorial(n):2 F5 q1 M# C4 F0 f* |; D: h* O
# Base case7 v% o |1 }* |: O/ E: e
if n == 0:; s& X6 N. | c1 U. U% t% I* n
return 1 ( E' G! ?# C% o9 g # Recursive case. n; p6 r$ ]1 R* [" R9 |
else:# V2 A' P% }+ `0 A4 E
return n * factorial(n - 1) " z7 K' v: H2 Q0 U' k( R% Y9 o 1 `' X2 i; b( i3 c8 `+ K* L, T* {+ T' u# Example usage + ~/ e7 q0 H) `6 r2 K h& Q7 Gprint(factorial(5)) # Output: 120 , a% r' D9 x: u: d- M- q: ?! u) f& |7 u. V: M
How Recursion Works * @$ S4 c1 F; z$ Z7 B$ B- @ ]) S0 M l% p! C; z The function keeps calling itself with smaller inputs until it reaches the base case. ( X: v6 z9 l# w3 C3 o. [9 Q: ^ ; P: s7 Y- P8 j+ r Once the base case is reached, the function starts returning values back up the call stack. 7 m+ m1 |4 M# T9 X& ]2 {$ z1 W8 i8 U0 ]# R1 m% p( W) q' I( T! C
These returned values are combined to produce the final result. 7 i# f: B+ V$ X" X4 Y5 \+ W0 N/ o " C: a! I6 l8 b' N2 P2 EFor factorial(5):, M( s" M4 Z, c1 h0 T
2 W R& f6 f5 k: I" d
+ P& f1 G- i0 y7 K9 z- Y
factorial(5) = 5 * factorial(4) $ c* G% K/ N7 x K. X+ L! Qfactorial(4) = 4 * factorial(3) - T, K: f' m9 I( g ?$ z) Z% x% j! Gfactorial(3) = 3 * factorial(2) 6 m5 N D, u. Y: ~9 sfactorial(2) = 2 * factorial(1)) {& d3 B/ ]$ e7 a# H/ Z. }( p
factorial(1) = 1 * factorial(0) & C5 S3 j* o3 b' \factorial(0) = 1 # Base case 2 B3 G2 | v d, K( ~5 N# Q$ \8 [* e' X7 \6 W( Q
Then, the results are combined:$ X, O7 v* U% M& B2 ~/ a$ u
- k# n/ d/ W5 N% t! J: C4 [* O) b! \
& X0 ]5 o0 c9 l/ L0 i8 }& l: {: Vfactorial(1) = 1 * 1 = 1 ) `; b! x' n& cfactorial(2) = 2 * 1 = 2 ! Q% x( r' c2 `1 M) n& Pfactorial(3) = 3 * 2 = 6! v* n2 a2 f/ ~
factorial(4) = 4 * 6 = 24 y: S. J. A& ~5 Y; m0 ufactorial(5) = 5 * 24 = 120 + g) w; u# V6 J( j* F 7 \* [& S/ Z" D6 {& x" u e: [2 fAdvantages of Recursion ' G4 \) U, ~8 C1 s1 Z# @5 U9 Q$ t* b9 S( u0 K* ^& V3 {
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).6 Q( d$ ?: i! v: d0 A3 p
% u& [9 ^- h& Q! n
Readability: Recursive code can be more readable and concise compared to iterative solutions.3 k* W4 c& i# R# ?
- ?6 |; P' V+ N3 c- jDisadvantages of Recursion 4 f8 T5 V1 {* S( p# ?# S4 H % @- K9 d& L# b! g9 z6 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.. U& @- l" s+ q& ]3 [0 Z# R% s
; }( @$ v$ @0 h% D! F
Inefficiency: Some problems can be solved more efficiently using iteration (e.g., Fibonacci sequence without memoization). " ?; [4 ]/ q; } % E, b" x. O" x% x* \When to Use Recursion P N! ]& b' N6 Y8 h
, V0 d: e+ I3 k2 M/ w
Problems that can be broken down into smaller, similar subproblems (e.g., tree traversals, sorting algorithms like quicksort and mergesort). 1 r6 z h1 y9 E4 K, E9 m' ]7 R9 J: Z1 K$ J& ]7 k. q! |+ F# @
Problems with a clear base case and recursive case.; k3 i: q' a+ H- R
9 v! }5 R' z4 _5 u2 \
Example: Fibonacci Sequence' j) |! D) |5 U0 K, o& |! l
% M$ H$ P m* o5 NThe Fibonacci sequence is another classic example of recursion. Each number is the sum of the two preceding ones:3 i) O1 O) u% E& b6 |2 Z" U) Z
. P" N8 q8 w8 K Base case: fib(0) = 0, fib(1) = 1 ; a% Z8 [3 x" R, G0 Y3 ~* z; { g$ e! F/ }' W3 H
Recursive case: fib(n) = fib(n-1) + fib(n-2) 5 q; f& y0 m% J" k3 u' c& F( e! v$ V7 ^5 y3 C
python! s- `* \; A1 y8 ?
! {$ T3 h, r' g* ?6 Q% A2 r# Y
* h$ T, ~" E# J3 d0 C
def fibonacci(n):# y, J5 d9 G# Z) d
# Base cases $ ^2 a3 I' a2 ` if n == 0: : X5 D8 _ T/ j" v( m( }+ Q return 0% T ` f. S, i8 ?/ n" y0 ?
elif n == 1: . ]7 ?: A% ]" F( N9 G+ j; F: B return 1 ( n/ f3 |2 z% t: C1 v# P # Recursive case ! N: B/ L, ?0 b: a4 N: q2 | else:% h) z1 e4 n3 _
return fibonacci(n - 1) + fibonacci(n - 2)6 N3 d. J9 i! L" ?
4 D0 r6 O" A: a _6 ?) L4 w# f
# Example usage2 M ~! ^# P) ^1 N! B$ R
print(fibonacci(6)) # Output: 8) E; Y6 R3 m; z/ R/ Q& z
, @1 y- h' k) t8 v) L
Tail Recursion 9 P% D. i8 Z1 i8 F ) | Z/ q- R B% V; W( \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).% |: |8 D( n3 W% q. q* j* q
& f" a$ p4 I% ^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 现在的开发流程,让一个老同志复习复习,快忘光了。