9 C' U, V1 I9 c, g 关键要素0 T% |4 u! [7 @+ Q
1. **基线条件(Base Case)** : i5 }; G7 ]) S- m - 递归终止的条件,防止无限循环3 u) h4 B! L1 w; d1 \6 [
- 例如:计算阶乘时 n == 0 或 n == 1 时返回 1- E) s9 N: [/ m( B
) U$ O2 `! ?; y2. **递归条件(Recursive Case)**6 ]# p! ]- |4 o3 v1 G
- 将原问题分解为更小的子问题# T% R8 Y# `( D6 p8 w/ `
- 例如:n! = n × (n-1)! 5 X: m$ S" T5 h1 |$ u$ N4 F) a" _8 ]
经典示例:计算阶乘& E" h) d! ]9 d, v* b
python* T) b$ @3 C+ K
def factorial(n):' L4 ~* c* E* P0 s6 F' Y
if n == 0: # 基线条件% a7 t- o, |% A/ e1 N' ^6 M. ^
return 1 6 d& c+ u9 V, w+ P" ` else: # 递归条件" B0 m) m2 @* i2 k: H. q% n! H w* _
return n * factorial(n-1)% g5 I: e# B9 B) V2 Y! i4 Y' S! x
执行过程(以计算 3! 为例):6 A2 X7 U7 Y4 V5 V. |" j4 y" ~( z0 u- N
factorial(3) ' h( E2 V* X+ r5 z: m3 * factorial(2)+ @2 M* H2 `% q3 H0 R
3 * (2 * factorial(1)) g" e; N% E; E& C" ?3 * (2 * (1 * factorial(0)))& K0 ^7 Q$ f4 G5 D1 a- p- u
3 * (2 * (1 * 1)) = 6 ' A9 ]! e! t6 D+ ]1 U; [5 y2 l# c8 h: B/ N) x* A+ ~! k4 R# e
递归思维要点9 P0 Q- R/ k4 u- y- W
1. **信任递归**:假设子问题已经解决,专注当前层逻辑* u" h' W7 |. B" I; @/ v2 v: c* a0 z
2. **栈结构**:每次调用都会创建新的栈帧(内存空间) 8 o* k c3 N8 _3. **递推过程**:不断向下分解问题(递)- D8 l, J9 G* m6 |! j
4. **回溯过程**:组合子问题结果返回(归) % c! ^8 e: i- m$ @3 \$ y5 I. X/ M0 I 2 t4 z R9 g/ b8 P 注意事项 . S" g* H+ ]& G$ N d+ h+ w必须要有终止条件( W3 j) o7 j& m4 \: C, N
递归深度过大可能导致栈溢出(Python默认递归深度约1000层) 1 N. q: R4 L1 S" Y' ?某些问题用递归更直观(如树遍历),但效率可能不如迭代 ' v1 H6 B! _3 m7 e* H# F* K尾递归优化可以提升效率(但Python不支持)3 G2 D; v: b, v" |% D7 E
# P- R, u1 U+ n
递归 vs 迭代; A8 Q! m# O9 V5 ^
| | 递归 | 迭代 | # Q( f8 l5 a( A5 `. ^2 x1 m+ }|----------|-----------------------------|------------------|5 C* {3 C8 [( a b, k
| 实现方式 | 函数自调用 | 循环结构 |. D& @+ Q7 N8 Y R2 b* d6 N1 ^: ~1 j! ^+ u
| 内存消耗 | 需要维护调用栈(可能溢出) | 通常更节省内存 | 5 R* k4 y6 r8 [8 `( R| 代码可读性 | 对符合递归思维的问题更直观 | 线性流程更直接 |+ z2 I4 \5 u2 D6 ^8 r! @
| 适用场景 | 树结构、分治算法、回溯问题等 | 简单重复操作 | 3 T# f! g3 e6 J! l 7 ^9 \: A+ R% w$ ^1 q 经典递归应用场景 9 F# ^) D. M* s9 n, l% `8 O7 r1. 文件系统遍历(目录树结构) 1 T( s; S% K' t: W4 u9 Z7 W2. 快速排序/归并排序算法 $ H/ O; O) J! o. Z5 [ O6 u5 O4 t3. 汉诺塔问题 + q- W- {' H+ j1 V4. 二叉树遍历(前序/中序/后序)) r) p5 u4 F7 w# h
5. 生成所有可能的组合(回溯算法)$ D. `1 p. g% b* ^& r7 s% S! v" Y4 p
4 h( ]) r7 I: e6 c( K; j" u- |9 ?4 G
试着用递归思维想象:你站在一面镜子前,镜子里有无数个逐渐变小的你在照镜子,这就是递归的直观体现。但记住每个"分身"最终都要有结束的时刻,这就是基线条件的重要性。作者: testjhy 时间: 2025-1-30 00:07
挺好,递归思维要点与我能够回忆起来我当时写递归程序的思路很一致,,或者被它唤醒," y9 `& ?8 k6 ^; u+ S5 X; q0 `
我推理机的核心算法应该是二叉树遍历的变种。 ! D4 _: _ C2 s) [" v另外知识系统的推理机搜索深度(递归深度)并不长,没有超过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:$ T4 B7 n6 L( P7 s
Key Idea of Recursion 5 O q, h! f( s7 \ * o% B! M$ s- i% M+ q+ {0 QA recursive function solves a problem by: 8 }+ t. M4 o7 a% R$ m/ Y0 G2 a ' ^; H' Z/ d2 v Breaking the problem into smaller instances of the same problem.% \, G- X7 W& F+ d& f; E2 V9 t
/ M/ E0 _. ^7 c1 w% ~ Solving the smallest instance directly (base case).) G# e6 W0 f3 C% \9 Y8 t8 M! b$ ?
. q, j# V6 o; a* h
Combining the results of smaller instances to solve the larger problem. 2 g/ X b: _# d; e, ]+ |- s( ^/ @+ p$ s9 _/ T( j
Components of a Recursive Function! {& E" ]+ H( U
8 f# ^9 y( _: f) z
Base Case: . I$ C& i( {6 [( q$ e- g/ V 8 S0 \( S K5 v0 m) v, _ This is the simplest, smallest instance of the problem that can be solved directly without further recursion.5 R* w/ y8 ~4 G0 @1 g& z+ L
0 t1 X4 s( C$ e, A
It acts as the stopping condition to prevent infinite recursion. 1 y( v2 r4 {; k3 A+ @- s $ ~. V( N# ~5 L( x% n. k" _ Example: In calculating the factorial of a number, the base case is factorial(0) = 1.4 Y" q; q1 K _. c- q) e/ ]5 v1 Z
# y: i3 m, @* c# D) h Recursive Case: 8 }* j% d) N, B; j5 C" I7 a( [+ Q5 X
This is where the function calls itself with a smaller or simpler version of the problem.) j n7 o7 T+ i6 Z
; {- I6 t u6 _2 P+ X0 Q4 l" M
Example: For factorial, the recursive case is factorial(n) = n * factorial(n-1). - s6 U- c2 U' ]- {# I6 Q/ D4 G& P+ {5 m, }
Example: Factorial Calculation % r# @! N4 ]" ]- p, W1 N8 X7 f( b* \3 p
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:: S3 c* W) E6 ^& e. ]1 A; W# e$ z
: h. z( C2 y- w* h* K1 y2 B/ P Base case: 0! = 1, P. w W6 i( C! B* [9 X4 k
9 u4 b' ]7 k& D D- L! e! L: p
Recursive case: n! = n * (n-1)!$ U+ ^$ {, K4 F7 p8 ]
$ U, S$ `6 L# d
Here’s how it looks in code (Python):3 r# y# ~" v3 [) ~/ Q
python- k. A6 m6 f: B+ }. t/ H# d
+ Y4 f9 Z0 y' a/ D: F7 L3 `5 }- _( i
, W/ U1 c' C, [( H+ Xdef factorial(n): . x% \$ a) r4 u" N # Base case 0 X% ~+ _$ F! H) b# w' q if n == 0: 0 \$ l7 J) v) s8 k- G) x3 h return 1 0 h9 ?/ D6 J& z1 s7 E # Recursive case " k& `, R! F8 [ else: 5 A& {0 @+ W- G5 M return n * factorial(n - 1)+ D) g: `( a0 s5 g& m8 Y
% Q0 x) \* [% ~# C2 J# Example usage Q- F8 R% g7 V) l
print(factorial(5)) # Output: 120 A+ d) w6 [6 B* W) u' Z/ x" |
( p; e) U& K. k# d7 \
How Recursion Works 3 W% U4 a X- N' [( S. o- ?0 V1 C/ k( B5 L( J8 ^! h
The function keeps calling itself with smaller inputs until it reaches the base case.% @5 s+ G0 r( q! {0 P' ]( Y+ S
; l+ O- g, W: j [7 ~# a; u
Once the base case is reached, the function starts returning values back up the call stack. / B' ^) o A+ g$ S$ m. a$ i& q: A1 n
These returned values are combined to produce the final result.7 t7 [ P/ G9 F5 q! I
& \* Q+ B6 Z9 U( v3 ^1 CFor factorial(5): 8 v; y, i6 [; h. n; v 5 x. Z; Q% o! v/ o; e' O N, H3 `2 Y$ ifactorial(5) = 5 * factorial(4). L8 B& k; W7 b0 H" Q( b0 M5 v
factorial(4) = 4 * factorial(3) * M% x2 S% e+ L; vfactorial(3) = 3 * factorial(2) $ U- E% T7 u2 E/ L# t$ xfactorial(2) = 2 * factorial(1) 1 r1 z+ Z% z3 L" }/ `/ Ffactorial(1) = 1 * factorial(0) # r. O7 {% Z$ E2 m+ Z( I1 d2 Cfactorial(0) = 1 # Base case. H k E0 d" a3 f: d" O
! _; Q; p% b8 h$ {' 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). 1 ~& |$ q) |! m" ~+ R7 F8 c* w9 G2 w, R( l6 p
Readability: Recursive code can be more readable and concise compared to iterative solutions. & H: t: R% n8 [5 j7 P0 D7 g: H! C ]. t0 h7 Z9 v
Disadvantages of Recursion$ d1 S+ X5 r% D# I- J- E
4 }2 H: G$ q; [- z 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 D! _# T0 u: W" n) M; d3 J" { p" i# d" v1 [9 U- L
Inefficiency: Some problems can be solved more efficiently using iteration (e.g., Fibonacci sequence without memoization). 2 m( R( q* _4 n( q1 ]$ u: ~4 z+ g2 K- A: E V
When to Use Recursion/ `% e- I( w- O
, P# q! H6 h! n7 o% @
Problems that can be broken down into smaller, similar subproblems (e.g., tree traversals, sorting algorithms like quicksort and mergesort).0 C% ?6 R: H4 x4 A
) b% s' v* U a
Problems with a clear base case and recursive case.4 V, G0 _- R F5 k9 E
; g/ n* e8 n' H8 }% f
Example: Fibonacci Sequence 0 T; d, ?2 C' l 8 @, L% C- U# pThe Fibonacci sequence is another classic example of recursion. Each number is the sum of the two preceding ones: + |. v3 i4 J/ d 3 [" C# ^$ y( H# A$ y Base case: fib(0) = 0, fib(1) = 1* L( B( F" Z& d; e
1 Q) @5 r3 i/ C1 J }. l7 B
Recursive case: fib(n) = fib(n-1) + fib(n-2) ) `$ k: h' O- o5 l! p8 a 2 O* W: Q) s+ P" m/ \. U+ ypython 5 R) V$ ]7 P0 v2 W! z& V 7 a5 Q; _$ b; z- N `' B, S, q6 q) f$ C% M$ {2 Y' v6 y B5 W* g" ?. G) `
def fibonacci(n): ) U ?0 P ?3 T, p # Base cases( E. Y) f e+ V* F6 [9 G/ Q; O8 b7 v/ f
if n == 0:/ P0 e, |/ B: u E# c6 {( {
return 0 $ I% E3 D; h6 ^, u1 _ elif n == 1:+ G8 i' g2 `* z+ X7 F' G9 Y' K
return 17 \5 e: I; I6 G" v+ f
# Recursive case' W y0 a. x6 }, ]" J4 b! E
else: $ {- H. k ?" Z$ l! q0 b return fibonacci(n - 1) + fibonacci(n - 2)$ a( j& b. C& q0 F1 A
4 j5 Y/ Z4 Y1 g( t' S/ i3 l. W @# Example usage 4 ^( J" x- o3 I# b5 wprint(fibonacci(6)) # Output: 83 z: `# U2 G* h" @+ ^
2 P+ \' _; B0 W" k- a
Tail Recursion # w8 }( r) ?, L" B8 L5 ]! {! L( X- z( D9 g2 Q/ ?
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).* t- Z: g6 Q. C, g2 G
+ t4 ^+ K e$ V3 d" e8 c
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 现在的开发流程,让一个老同志复习复习,快忘光了。