* h$ E) _) w6 o, Q" H& a$ y' P递归是一种通过将问题分解为更小的同类子问题来解决问题的方法。它的核心思想是:**函数直接或间接地调用自身**,直到满足终止条件。 + w2 |1 D4 c( ~2 G1 K% h4 G$ }, R0 N2 |$ n5 E7 l
关键要素 + j5 }( Q$ b+ @ x& x1 F1 v. W- q1. **基线条件(Base Case)**: V M) _2 {4 i k+ l; d/ ^
- 递归终止的条件,防止无限循环# o( p0 ^ D! g( n5 L
- 例如:计算阶乘时 n == 0 或 n == 1 时返回 1& e5 i) O9 e) ?5 O& |9 e$ C) G
# h+ |/ h0 n5 C2. **递归条件(Recursive Case)** 4 I% m G1 w) g& Z5 u - 将原问题分解为更小的子问题& a! x- c9 I+ o" k$ y9 w& T
- 例如:n! = n × (n-1)!0 c f' n8 D* `4 Z
9 c8 g# M- y" a! t) \) J
经典示例:计算阶乘 # ^. p, p8 R1 I- Gpython+ Y6 ?) }9 X2 _ {) x
def factorial(n): 7 r6 f d& \7 t! g+ J9 y if n == 0: # 基线条件 7 n0 c, W+ _: D return 1& T7 J2 W* W& \$ D; ~: m1 _1 g
else: # 递归条件 . \. V L# g9 H% X% P+ L: L5 x return n * factorial(n-1)0 Y0 {$ Q; f, C, \
执行过程(以计算 3! 为例):7 K* Z& @' o% ^% e# m! k( H
factorial(3)7 A$ K, e9 N0 B$ h8 U# r
3 * factorial(2)5 v# P, G+ V# B% M% s$ d
3 * (2 * factorial(1)) o! O' U' ~+ L, P3 k5 n, V3 y3 * (2 * (1 * factorial(0))) $ @% b r4 O% |) F6 z- S3 Y3 * (2 * (1 * 1)) = 6- H7 h8 q- Y9 O% g
: n2 x* k$ I/ N% t3 L/ I D 递归思维要点) A N9 W/ I* U2 R$ I
1. **信任递归**:假设子问题已经解决,专注当前层逻辑9 ^4 y3 h5 s( q9 k: {( `8 T9 J
2. **栈结构**:每次调用都会创建新的栈帧(内存空间), ] X7 X) z8 Z. b( O' Y
3. **递推过程**:不断向下分解问题(递)/ y( p/ G$ k. y0 g' F1 J
4. **回溯过程**:组合子问题结果返回(归)# k! ^0 G1 a! M6 }" X% @ J1 S
4 c) N% y" Y3 q5 T) l
注意事项# w, B D# H# [( z) O0 W( y+ w B/ ^
必须要有终止条件" j: M. O$ v& z) A
递归深度过大可能导致栈溢出(Python默认递归深度约1000层)! B6 }! T7 T% z! D/ i
某些问题用递归更直观(如树遍历),但效率可能不如迭代 3 C( B1 f7 V; d" @; L8 U1 f尾递归优化可以提升效率(但Python不支持)5 k; n$ {6 e9 H" ^7 Z# H3 l3 X
, ~/ \& l: A( p+ b) X; o' V x 递归 vs 迭代 + Q6 `) g( N5 E, m6 I$ C| | 递归 | 迭代 |- B; |) z+ X9 `- f, Q7 a" I4 p
|----------|-----------------------------|------------------| : J Q: q8 S7 n Q, U| 实现方式 | 函数自调用 | 循环结构 |, Z) I) L# o" ]2 h. P8 N+ k
| 内存消耗 | 需要维护调用栈(可能溢出) | 通常更节省内存 | # j6 b5 U K$ g0 t4 D: m| 代码可读性 | 对符合递归思维的问题更直观 | 线性流程更直接 |4 Z8 k1 U; h# D* z/ w/ d6 y; O
| 适用场景 | 树结构、分治算法、回溯问题等 | 简单重复操作 | ' X0 [$ P5 m- X6 t& u ) P, f' B. ^. W; H 经典递归应用场景 % a+ ^8 ~" y7 Y1. 文件系统遍历(目录树结构)& S( a6 o4 U. K; L
2. 快速排序/归并排序算法 ' G" l. q1 ]! h& Q( l# J# i3. 汉诺塔问题; {' k* a# C6 v9 m
4. 二叉树遍历(前序/中序/后序) 6 [7 g. a% N$ j5. 生成所有可能的组合(回溯算法)7 \0 D+ A: m+ }7 S
4 S/ C% c, n x: z9 t: v
试着用递归思维想象:你站在一面镜子前,镜子里有无数个逐渐变小的你在照镜子,这就是递归的直观体现。但记住每个"分身"最终都要有结束的时刻,这就是基线条件的重要性。作者: testjhy 时间: 2025-1-30 00:07
挺好,递归思维要点与我能够回忆起来我当时写递归程序的思路很一致,,或者被它唤醒, ; I6 o$ G4 d5 g我推理机的核心算法应该是二叉树遍历的变种。/ ]6 s0 S. W | F
另外知识系统的推理机搜索深度(递归深度)并不长,没有超过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:1 c9 M; V5 _& G8 C- J) j+ K
Key Idea of Recursion& X5 Y) x, U% W- S- F( ?! v) @
# p$ E+ \/ ^; `, A+ n2 m9 E7 ~
A recursive function solves a problem by: 7 ^* F" ^0 b- U7 B; X % H9 b6 q3 k1 L% [! E- J; Q Breaking the problem into smaller instances of the same problem. , ?3 B: _6 W; Z1 a( L! x% e 7 d0 t1 D" ?' e& I# g& s8 W, t Solving the smallest instance directly (base case). |3 s R* I$ G, o, J; Y I
% K: x: \* ?0 C5 U0 t6 A6 O Combining the results of smaller instances to solve the larger problem. ! A' I* _+ c/ u7 {9 f+ L1 g8 W5 y2 \( u4 g1 b
Components of a Recursive Function! y$ F1 m# i C
" \6 E8 H, x4 O" M Base Case:" P0 e8 U; |" A6 z. n. |. R1 z; t
8 g; e! V& t' l( X4 q; J! N% L This is the simplest, smallest instance of the problem that can be solved directly without further recursion. # g. i/ i/ D4 ~, S* k: [% z % R( ~* W" \# K- m: [4 N It acts as the stopping condition to prevent infinite recursion. % `2 D2 _8 S' v ! H. M9 l/ [5 E7 n Example: In calculating the factorial of a number, the base case is factorial(0) = 1.! [. u- t p/ l$ M) f8 B9 X% e" K
% C2 h! t k4 L5 |$ z
Recursive Case: 4 b0 M2 H/ ~7 ^/ h4 _ : d7 e9 a! b, z! G& T7 r This is where the function calls itself with a smaller or simpler version of the problem. 2 n: L9 c; y, Q% g7 ~$ s) f ( E7 P0 x' ?. Q9 U: S Example: For factorial, the recursive case is factorial(n) = n * factorial(n-1).& N! _+ [5 \+ i4 K/ h- l
$ {! J8 I J9 o
Example: Factorial Calculation 8 h0 }' F" P0 d( D c , `; S. s% @- H! c/ i: v, RThe 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:, U1 g" m) k# N0 V$ p$ m
9 [* A4 b: b0 k o, F0 l Base case: 0! = 1 " @) }4 u; T( Y7 H, B* R) ^6 c4 |
Recursive case: n! = n * (n-1)! ' x' F5 y6 C0 }- k1 w ^5 t# U; I2 h* P1 w* Z
Here’s how it looks in code (Python):9 t8 l; T, v# | J, [# I0 E* o
python ) F0 x4 z7 G1 l) `% _+ c9 A# F" w" h, f h' F
/ T" K$ f$ d* t8 T
def factorial(n):: o2 J4 }9 Z. W: [' C
# Base case j! ?1 Y! o1 b( S7 W% Z if n == 0:7 b% X; W7 |+ `8 C' x
return 1 d/ c! ~) f K0 R4 i8 [* Q # Recursive case 8 q! a6 R8 z5 U else:4 U" g0 M4 S2 E9 n% Z+ ^" y
return n * factorial(n - 1)4 v! o' O0 ^& r: E/ G% M
( Q) l3 r/ g* {: c, a/ ?
# Example usage# j& f+ d/ }1 K5 W8 J: f/ U! R
print(factorial(5)) # Output: 120# J$ ^, Q5 u2 o' m4 h0 z7 N% M
# j9 F* P, @9 f) X" L3 `8 ~ The function keeps calling itself with smaller inputs until it reaches the base case.- }) J4 Y$ G+ Q8 N/ v, O& p
1 W5 `0 {* S/ D' e Once the base case is reached, the function starts returning values back up the call stack.5 o6 W0 @) ]: H" K7 @/ g
4 \. \+ g# t+ Y9 Z
These returned values are combined to produce the final result. 1 |0 m( z, y! } 5 _7 p; \/ ?: U5 S1 t4 v HFor factorial(5): 6 Y8 o/ n9 Y2 j( e5 V; b 3 ~2 m6 f. U7 _/ h C: s5 R4 I' x5 e1 f5 G' ?2 h
factorial(5) = 5 * factorial(4) 2 ]* _* L7 r' u i- F1 W6 kfactorial(4) = 4 * factorial(3)5 y2 }" s! }! b
factorial(3) = 3 * factorial(2) . C8 Z& l8 ]: c# W( e; \" [4 tfactorial(2) = 2 * factorial(1)* v+ j( e5 Z% f6 h# O/ f8 A
factorial(1) = 1 * factorial(0) 3 r0 h' m( k4 d+ R+ T1 q1 Yfactorial(0) = 1 # Base case # X j" j7 Q2 E% W# T- p; G7 C9 L: S; [
Then, the results are combined: 3 n- t( G+ x1 A0 o7 s2 ` ! m( ~) R4 ] w7 S+ L # o: H$ c( c8 efactorial(1) = 1 * 1 = 19 G7 a: |% d7 d0 i
factorial(2) = 2 * 1 = 23 S5 P+ P' Z3 j8 F6 i
factorial(3) = 3 * 2 = 6 : I' p3 h& }; I+ I' p1 {! Wfactorial(4) = 4 * 6 = 24# m7 q4 X* R# E: Y2 r
factorial(5) = 5 * 24 = 120 / C; F% E A. P ; x& t1 B5 q" T F6 iAdvantages of Recursion7 z; k1 V* ~ { p' e
; v4 v \# k5 b# O
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).2 g, u: I4 z/ T7 C
8 U; B" k1 R) F9 c
Readability: Recursive code can be more readable and concise compared to iterative solutions. ; f7 @8 O$ q4 r% _6 e. H. u6 l: M2 w. ]* {2 C: i
Disadvantages of Recursion : B( f8 @! M% b3 ~. |4 j' z S3 G j
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.- o8 g$ W% h" I$ }3 T* `
! ^2 a) K( }6 S1 b* p+ b3 P
Inefficiency: Some problems can be solved more efficiently using iteration (e.g., Fibonacci sequence without memoization). * k3 O2 I& c7 E 4 E0 G4 h- x! g/ F& rWhen to Use Recursion4 L9 L6 m# K' Q6 ^5 N
- k/ h% ], I1 Z- M1 i
Problems that can be broken down into smaller, similar subproblems (e.g., tree traversals, sorting algorithms like quicksort and mergesort).3 U: A7 w* m% X" D2 \3 I$ k
& C- V0 U3 u' V4 n( l8 Q" a2 J' H Problems with a clear base case and recursive case.( | U; e* ?/ Q) E; R1 ~3 v
) l6 l6 w# X5 f! DExample: Fibonacci Sequence: ?9 f4 o- O( @. h/ | o$ U
8 p" g$ q9 h# z7 E1 q3 K3 {/ }: ?
The Fibonacci sequence is another classic example of recursion. Each number is the sum of the two preceding ones: ! y; R: c6 [1 F+ Q x& z ( N& Z, j% N+ Y. [9 J Base case: fib(0) = 0, fib(1) = 1 9 p6 ^4 g) L( v! f3 x) @0 F5 |- {$ X+ R' @& [7 T) ?/ l! v
Recursive case: fib(n) = fib(n-1) + fib(n-2) 5 D$ F2 t/ T& [- j& r$ y8 s" }/ _4 g9 M( P) G7 J0 @5 ~7 C
python" l+ N1 S! N% G3 N' M+ c
/ x x# f- X( p. B8 B, `0 i
8 ^0 r' ^' j, _7 I3 P9 g
def fibonacci(n): - [9 c4 X0 t% R1 t& ^) s/ d # Base cases 8 z. G2 q% d$ A% S. d, D if n == 0: ; N, D" P- o1 Q. E. w return 0 1 y9 \" R1 w" b& ^4 e: S elif n == 1:. Q- ^+ \# S! F( [/ ?% _0 x
return 1. @, z8 p: `1 Z8 t8 S d& Y5 d
# Recursive case! W5 N0 M7 O' L# |) h& |
else: # n" e/ {! M% R2 @ return fibonacci(n - 1) + fibonacci(n - 2)# J: y6 n ^4 w
3 k- ]$ U9 y Z6 UTail 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). " W8 z$ R a- C$ _# p) A+ ? ) z0 j+ ?1 \1 m5 e: JIn 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 现在的开发流程,让一个老同志复习复习,快忘光了。