; q' ^6 a) G! D* g. m递归是一种通过将问题分解为更小的同类子问题来解决问题的方法。它的核心思想是:**函数直接或间接地调用自身**,直到满足终止条件。 / J2 o& B% C, y( |0 Z2 | 7 j9 k. K1 v. O; ~& E1 b 关键要素, g" ?, O4 V4 Q7 G2 t8 H
1. **基线条件(Base Case)*** i; A( A* i1 J+ e0 B
- 递归终止的条件,防止无限循环 / U+ f T! S+ F( o/ T - 例如:计算阶乘时 n == 0 或 n == 1 时返回 1 5 h8 H0 X" V C1 D " C2 l1 S" l( @5 m; \; Y5 s2. **递归条件(Recursive Case)**' l) }' I& X9 |3 Z/ @( B
- 将原问题分解为更小的子问题 ; N5 _4 b, n% ?1 ^ - 例如:n! = n × (n-1)!6 B2 ~" D+ {$ Q3 R" j3 P
, t4 q$ M; d$ N9 }" Y; |) b! M
经典示例:计算阶乘9 u( \8 ~3 H& g7 X# a
python: s" X, j( P7 s' ^- Q+ ^1 n
def factorial(n): 0 @4 B. t2 t6 d0 z/ s, g( G if n == 0: # 基线条件 9 r( x' L+ T- w# @; N- j2 E return 1( h( m) X9 j$ u0 c- q
else: # 递归条件4 O5 Y4 N6 l/ J! r4 S" ]5 q
return n * factorial(n-1) 3 i- {4 S" A0 L" R: |执行过程(以计算 3! 为例): 8 _/ G B" i" h$ |+ |2 w4 Lfactorial(3)% P; X) O5 @8 |+ ]
3 * factorial(2)6 `2 T( `, }: r6 ^
3 * (2 * factorial(1))+ o+ i' a) V$ g, X
3 * (2 * (1 * factorial(0)))6 V( L X8 K: F
3 * (2 * (1 * 1)) = 6 4 E7 S6 d2 N7 R7 p) ~. U. J8 I* w1 E- I0 d% {& l$ x
递归思维要点 1 q: T" Q. D7 V' B: Q% {' [1 T1. **信任递归**:假设子问题已经解决,专注当前层逻辑( ?- W* B$ j2 T. B
2. **栈结构**:每次调用都会创建新的栈帧(内存空间)& \$ s- e$ o1 n5 `3 |2 v
3. **递推过程**:不断向下分解问题(递). E5 G1 J2 E1 v! x
4. **回溯过程**:组合子问题结果返回(归) " P3 U6 A; C; Y2 |6 K- k' R u4 y% W5 q; ~, H5 B' W- T* l: M 注意事项 M# t1 e6 G" }" z
必须要有终止条件 $ ^8 F( G4 ~' @% r0 j$ {+ D/ |递归深度过大可能导致栈溢出(Python默认递归深度约1000层) 2 F/ D% x$ P/ t! M/ s7 h) x某些问题用递归更直观(如树遍历),但效率可能不如迭代 7 S4 x4 [3 O, D0 Q4 ~, M. D尾递归优化可以提升效率(但Python不支持)9 m+ V5 @8 {7 c, ^+ t5 ~- E& x
7 `( Y" x4 W! ~( V i# f4 A 递归 vs 迭代 % z0 u- m4 N( j8 R| | 递归 | 迭代 | ( k- F7 j3 b* J7 l. l# [" d# D|----------|-----------------------------|------------------|! k' g( d. c# X, p; l+ b
| 实现方式 | 函数自调用 | 循环结构 | l, U% r/ T" [9 C& R" v| 内存消耗 | 需要维护调用栈(可能溢出) | 通常更节省内存 | 4 v4 |" y3 q& R| 代码可读性 | 对符合递归思维的问题更直观 | 线性流程更直接 | 6 w0 Z j) z% r( g" ?| 适用场景 | 树结构、分治算法、回溯问题等 | 简单重复操作 |; ~: d1 \4 b& b1 K" b) C+ e
/ r# C% P% o* h' x! i0 E& @ 经典递归应用场景 + o6 n0 ?8 {( c8 d1. 文件系统遍历(目录树结构)# B* Z o# s* P4 e" O, {
2. 快速排序/归并排序算法8 S* o9 E7 k4 W% J; d
3. 汉诺塔问题 % ^+ a( ^7 _# W8 p: k; ^4. 二叉树遍历(前序/中序/后序)7 b% B1 V7 \7 g- q- f
5. 生成所有可能的组合(回溯算法) 7 M4 p* E" E6 I- b3 Z+ z6 D, s9 C6 S% R' h$ F% B
试着用递归思维想象:你站在一面镜子前,镜子里有无数个逐渐变小的你在照镜子,这就是递归的直观体现。但记住每个"分身"最终都要有结束的时刻,这就是基线条件的重要性。作者: testjhy 时间: 2025-1-30 00:07
挺好,递归思维要点与我能够回忆起来我当时写递归程序的思路很一致,,或者被它唤醒, " @% ^$ W0 [' N4 L2 ]8 k8 r6 L$ \1 f; Q我推理机的核心算法应该是二叉树遍历的变种。0 v( R1 o0 f" Z2 Q
另外知识系统的推理机搜索深度(递归深度)并不长,没有超过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:& N* v: N( p$ k' ^$ g( s6 [% c/ U% z
Key Idea of Recursion + n) J( ~: N7 @2 ?2 Q* ?% a$ P% B) s. ^( G+ I( T
A recursive function solves a problem by: 9 q! `1 c+ s3 l, ]" F. t 6 ?" P+ N: l( `8 y, ~' Z Breaking the problem into smaller instances of the same problem.1 o# l4 _8 C, N# a$ d/ l. R. S8 d
! p Q/ ]% Z7 t2 H Solving the smallest instance directly (base case). " m0 P$ Q. v5 d% ]/ \ 7 l9 i% G( T* d0 T Combining the results of smaller instances to solve the larger problem.' D: F- E2 I; F7 b: x1 t
( Y0 |0 O, l2 q0 `+ v7 AComponents of a Recursive Function! o+ i! @" m3 N% {* s
k( {: U" R" E7 G Base Case:1 y2 f& m5 |: r* ^
6 w- k) o8 R9 I This is the simplest, smallest instance of the problem that can be solved directly without further recursion. 7 h! X7 S/ t, X6 j$ d% Z: ~+ t3 I3 T' c0 b
It acts as the stopping condition to prevent infinite recursion.* E7 P4 `7 `+ c. E: m" o- A: R+ G
+ E( ]7 r/ t$ [+ `% Q Example: In calculating the factorial of a number, the base case is factorial(0) = 1. @- k ]9 b" W* p: U0 W( [% Z
, o/ H3 J5 ~+ d% w* V5 c- a
Recursive Case: 3 D9 i. b" X$ V7 c) y! ` p 6 k/ @+ m; G% R% m* I' M This is where the function calls itself with a smaller or simpler version of the problem. ; A c% {1 U* w6 {/ g! v* o% m4 q " U- U/ }- M- j6 u6 }7 N Example: For factorial, the recursive case is factorial(n) = n * factorial(n-1). 1 F( k! b5 R" L; h/ z0 J0 B) F - ~7 i& X: G$ }) SExample: Factorial Calculation" w% h( b! E* M, q+ |
' B5 A. D: t6 \9 ^% u0 iThe 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: c$ V5 c% R- X) e2 I$ Y* l3 q+ W- w4 B/ n7 h
Base case: 0! = 1( {. h7 N0 f1 f9 o7 S4 n
# [: w3 p4 N3 s- ?2 @. Q Recursive case: n! = n * (n-1)! # y d* M% p' T6 D% N, o4 |+ ?% Z; o' V- M( L; X1 Z2 T) u
Here’s how it looks in code (Python):; e5 E* K) o$ @/ F' Z% J, k
python d6 J+ X8 j2 f. J- ]' A0 S H : q( a% }9 t3 V % H* B% f( Y% l, J. M7 e# Odef factorial(n): ) f4 r) s8 Q" h. g: D6 Y/ s # Base case ! q2 ` j" I, P* p if n == 0: 5 W( B! i* t& ]" G4 k return 1 ( ]5 t/ O) i$ g4 A9 W # Recursive case* K3 \* P4 _5 R @, f' R: O
else: : S& F1 ^) M& L3 X+ X return n * factorial(n - 1)/ x) Z# W- b" A3 _" c- y
B. ^9 d7 l& D. g# x) f
# Example usage 1 D" f: P7 f1 }. y1 W" M2 B0 Z# \print(factorial(5)) # Output: 120$ s- U% |3 e" X7 Y3 E# {: x) `
' u8 V X1 o( W! q% E( RHow Recursion Works2 p$ x I9 r/ g. n
, @* V% a, s% {9 H, r- A6 V! [ The function keeps calling itself with smaller inputs until it reaches the base case. % } R ~3 M& P" N0 j: M3 r0 E I2 J3 A" y" q3 h0 W t
Once the base case is reached, the function starts returning values back up the call stack. 1 a# _6 O8 V6 @, F5 W $ M- e5 G# g5 I These returned values are combined to produce the final result. ! z0 f1 S% G' N% ]3 E; q0 `3 q/ |* o7 E: U: J' H" O. \
For factorial(5): % _8 l3 v1 z+ F$ X* [7 `- H; q8 o) K/ r3 e6 x
, t {) f8 N/ i8 J# V8 n; @( X' I8 ?
factorial(5) = 5 * factorial(4)' G% P4 d$ s9 H) L4 C! Z# E
factorial(4) = 4 * factorial(3) 6 a* a6 P* v6 _% r& {# T8 dfactorial(3) = 3 * factorial(2) 2 i) ~+ y k9 D( O( T) ofactorial(2) = 2 * factorial(1). B0 S+ z( A* ?! o
factorial(1) = 1 * factorial(0)9 Y0 U& `# l. p4 X. A+ m
factorial(0) = 1 # Base case, k+ c' v4 Z: J
* ^# S) G2 {6 a. e+ v! k
Then, the results are combined:# o, G' T: o4 \/ L: `* S* N9 k
& T1 A4 e. D0 g" J! `/ f' h9 K1 l; i9 {
. d- C1 P7 c# P5 F/ Cfactorial(1) = 1 * 1 = 12 u+ h+ a# b, E: B
factorial(2) = 2 * 1 = 2 7 Q/ m% Y% U6 L, Y- Sfactorial(3) = 3 * 2 = 6 3 P f! ?2 A- e+ Qfactorial(4) = 4 * 6 = 24 " ^5 B, n5 y7 e9 jfactorial(5) = 5 * 24 = 120, m0 R8 j/ F( p& `
! C J; K1 r; t |$ @/ l& Z
Advantages of Recursion ) [1 N1 X, e8 b/ I, x* h! M. B* r) e- i, ^# R" ] V- B1 U6 |; |# Q
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).0 q8 W$ }2 G) B3 l* p- h- S
5 r# J5 ]! Y, D8 E( S: W
Readability: Recursive code can be more readable and concise compared to iterative solutions.8 P0 s9 R; x$ f3 M
. K: |2 R; q$ kDisadvantages of Recursion4 k; o9 J6 r9 q" L$ l F
$ G ^: {, z$ h# [ 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. # ~. |& z( T! I: M2 E : g5 _: b1 P0 }. ]9 c Inefficiency: Some problems can be solved more efficiently using iteration (e.g., Fibonacci sequence without memoization). - s0 l/ f2 |- a. [4 {. h u2 a, Q5 f$ h5 _
When to Use Recursion $ @& j0 d3 l6 Y5 ?' B: \. P1 O7 Z. I% Q; b! I
Problems that can be broken down into smaller, similar subproblems (e.g., tree traversals, sorting algorithms like quicksort and mergesort).; ^ K, V+ _. x# D4 q2 I2 ]
) ~/ E1 h# v6 p0 S p; [9 g, `
Problems with a clear base case and recursive case. 3 ^4 R% O( K% r) _4 }$ ^ * q# U8 z. L/ Q/ x9 n L5 WExample: Fibonacci Sequence % @6 d; v: q& t& D- \+ `3 S3 K. e' I' B& `* w: F( Z/ w, c
The Fibonacci sequence is another classic example of recursion. Each number is the sum of the two preceding ones: ! j! y$ D& _& ~$ W6 t/ ]: \1 G5 D! K% D" z, k; T. y" v; e# ~
Base case: fib(0) = 0, fib(1) = 1 ; L, Q! b( m6 s) y8 d# x4 ]0 T( M/ M5 i% U/ `$ i
Recursive case: fib(n) = fib(n-1) + fib(n-2)5 U( J9 ~1 r) ^" m) s' ^6 T
/ ?0 x N+ U5 V; P7 z) T8 Q
python 3 ?. s' b( [: e4 {0 t5 V. x, r4 G% a
/ C3 R- m1 a6 N: ~. Z5 M
def fibonacci(n): ( p) X: v; g' g5 ]- N # Base cases5 `6 K; Y+ n L6 d$ z: v
if n == 0: ; `/ B; j( {; P7 w7 b# @2 l return 0$ @- _; }0 ^! o c
elif n == 1:' E r u7 K7 {' u1 \
return 1( G8 C# n) B) Y" u3 S
# Recursive case . D; c: `+ B6 h" ]1 I0 L* ? else: 8 B8 d2 w% {) q! v# n( T return fibonacci(n - 1) + fibonacci(n - 2) 6 s1 F8 u2 C: ^- l4 N( x1 A* G0 W, N6 x+ Y2 Q
# Example usage 6 o' X2 [9 j1 V; Rprint(fibonacci(6)) # Output: 8 / q9 f- B* [/ j& s4 o- ]0 V* }2 Y3 {6 n9 v9 v8 G O9 t
Tail Recursion 0 P Y6 c& i4 a a& ^+ ]2 n, R 5 H$ |- g) S9 gTail 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; Q6 o5 H5 S$ n; h [
1 E2 j' x, N, D0 f3 DIn 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 现在的开发流程,让一个老同志复习复习,快忘光了。